Here's a Netlogo-beginner question. I created a model where birds shall fly on a certain route. I created this route by placing 10 turtles I called "rasts" (resting place) on patches an linking them with each other. Now, I want to make the birds fly on these routes and when a resting place disappears (by using an "on/off"-switch), they shall take another route.
My problem: At the moment I have 5 rasts but only the first one can be shut off by using the switch. Has anybody an idea, how to fix this?
Here's my code:
breed [rasts rast]
breed [birds bird]
to setup
setup-rasts
hide-rasts1
hide-rasts2
hide-rasts3
hide-rasts4
hide-rasts5
end
to setup-rasts
set-default-shape rasts "circle"
create-rasts 1 [setxy -12 36 ]
end
to hide-rasts1
ifelse rast-1? [ ask rast (number-of-birds + 0) [ set hidden? true] ]
[ ask rast (number-of-birds + 0) [ set hidden? false] ]
end
For the first question:
Isn't it possible to make more than 1 turtle hide itself by using the
following code?
you can ask a list of turtles to hide:
; hide all turtles
ask turtles [ hide-turtle ]
; hide all your "rasts"
ask rasts[ hide-turtle ]
; hide random 4 of your turtles
ask n-of 4 turtles [ hide-turtle ]
As for the 2. question
Is it possible to make turtles (birds) follow a route an change it,
when there's another turtle (rast) in there way?
the answer is of course it is possible, but the question is somehow to general to suggest a precise solution. You can use the face command to point the turtle in the right direction. For sensing the nearest turtles check the turtles with min distance. For example (in turtle's context):
set nearest-rast min-one-of (other rasts) [ distance myself ]
Related
I am trying to extract multiple values from a log with the following format by using the extract_all() function:
v1=value1 v2=May 18 2021 v3=value3 v4=The dog jumps over the fence v5=192.168.1.1
The extract_all() formatting is the following:
extract_all(#"(?P<key>\w+)?=(?P<value>\S*)?", dynamic(["key","value"]), restconvert)
I have tried multiple ways in order to capture the full sentence of v4, but I haven't been able to. Among others, I have used (?P<value>\w+)?, (?P<value>\S* \d* \d*)?. The latter was able to capture the date without causing any problem to the string continuity. I have also tried the logical or in the second part of the regex in order to distinguish between cases with no success.
\w+( \w+)* and similar variations messed up with other values, such as IP addresses and with the continuity of the string.
I am not using the parse operator because the fields change through time.
Any hints?
This would have been a lot easier with negative lookahead, but RE2 doesn't support it apparently. This handles many spaces between words and skips spaces, but does include an extra space on the value, sometimes, if there are multiple spaces between value and the next key token.
print text="v1=value1 v2=May 18 2021 v3=value3 v4=The dog jumps over the fence"
| extend values = extract_all(#"(?P<key>\w+)=(?P<value>(?:\w+(?:\s?|\z))+)(?:\s|\z)", dynamic(["key","value"]
Results:
[
[
""v1"",
""value1 ""
],
[
""v2"",
""May 18 2021 ""
],
[
""v3"",
""value3 ""
],
[
""v4"",
""The dog jumps over the fence""
]
]
I have this kind of df:
df = pd.DataFrame({"text_column" : ['question: everybody is kongfu fighting', 'panda: of course', 'question: Why is the world so great ?', 'friend: Everybody is smart', 'and everybody is cool', 'enemy: no that is just not true', 'jordan: i want to add one thing: please', 'do not talk about this.', ' 2nd question : are you sure ?', 'yeah sure' ]})
text_column
0 question: everybody is kongfu fighting
1 panda: of course
2 question: Why is the world so great ?
3 friend: Everybody is smart
4 and everybody is cool
5 enemy: no that is just not true
6 jordan: i want to add one thing: please
7 do not talk about this.
8 2nd question : are you sure ?
9 messi: yeah sure
10 question: you are sure about this ?
11 donald: youre questions are stupid!
I want the following output
type_column new_text_column
0 question: panda: everybody is kongfu fighting of course
1 question: friend: enemy: jordan: 2nd question : messi: Why is the world so great ? Everybody is smart and everybody is cool no that is just not true i want to add one thing: please do not talk about this. are you sure ? yeah sure
2 question: donald: youre questions are stupid!
Basically each question and answer (topic) have to be in one cell.
I could write a function that works but would use apply, which is in general not an optimal solution.
Does anybody have a good idea how to do it?
Define the following functions:
"Specialized" split of the source text field into 2 parts:
def mySplit(txt):
tbl = re.split(': ?', txt, 1)
if len(tbl) == 1:
tbl.insert(0, '')
return pd.Series(tbl, index=['Qn', 'Ans'])
Reformat a group of rows:
def reformat(grp):
t1 = ': '.join(grp.Qn.tolist()) + ':'
t2 = ' '.join(grp.Ans.tolist())
return pd.Series([t1, t2], index=['type_column', 'new_text_column'])
Then, to get the result run:
df.text_column.apply(mySplit)\
.groupby(df2.Qn.str.startswith('question').cumsum())\
.apply(reformat).reset_index(drop=True)
It performs:
Specialized split of text_column into 2 columns (Qn and Ans).
Cut into groups starting on each row with Qn starting with question.
Apply reformat to each group.
Reset the index (discarding the old index).
It's hard to tell from the example what the criteria is for separating.
I'm guessing it's splitting on the colon, so you could try list comprehension
df["type_column"] = [x.split(":")[0] for x in df["text_column"]]
df["new_text_column"] = [x.split(":")[1] for x in df["text_column"]]
I have text in a cell which starts with [ and ends in ] and I want to show the text between these two characters.
So far I have this:
=LEFT(A2, SEARCH("]",A2)-1)
but it still shows as [1234. I just need to figure out how to remove the first [.
There are several ways. If you know your string always starts with [ and ends with ] then you could use:
=SUBSTITUTE(SUBSTITUTE(A2,"[",""),"]","")
If there may be text before [ and / or after ], then try:
=MID(A2,FIND("[",A2)+1,FIND("]",A2)-FIND("[",A2)-1)
If you want to "strip" the first and the last character, independently of what they are, you can do this:
=RIGHT(LEFT(RC[-1],LEN(RC[-1])-1),LEN(RC[-1])-2)
I want to save and restore a set of turtles in a file. I have something like this:
breed [squares square]
breed [circles circle]
squares-own [side-length]
circles-own [radius]
to save-agents
file-open "test"
file-write count turtles
ask turtles [
file-write xcor
file-write ycor
file-write breed
]
ask squares [
file-write side-length
]
ask circles [
file-write radius
]
file-close
end
to restore-agents
file-open "test"
let n file-read
crt n
ask turtles [
set xcor file-read
set ycor file-read
set breed file-read ;; Right here I get an error "Expected a constant. (line number 1,
] ;; character x) error while turtle y running FILE-READ"
ask squares [
set side-length file-read
]
ask circles [
set radius file-read
]
Looking at the file, I see the breeds are stored as unquoted character strings. It doesn't matter what I try to read the breed variable as; I get an error just manually going through a bunch of file-read statements.
I suppose I could intentionally code the breed as a string that I later interpret using a whole bunch of nested ifelse blocks (yuk). But it appears that the way NetLogo writes the breed variable is the same way it writes other constants like true and false. Is this a NetLogo bug? Is there an (elegant) work-around?
On further thought, I could count and store each kind of agent individually so when I go to restore I could create squares number-of-squares, etc. but I was really hoping not to have to handle every possible kind of breed this way. Suggestions?
Thanks,
Glenn
The runresult primitive can help you here: it allows to run code stored in a string.
If you save your breed using
file-write (word breed)
to make sure that NetLogo puts quotes around it, you can later restore it like this:
let breed-as-string file-read
set breed runresult breed-as-string
There are also other possible approaches for saving and restoring turtles:
export-world and import-world might be overkill here, since they save and restore the whole state of the NetLogo world, but they may be useful in other circomstances.
The nw:save-graphml and nw:load-graphml from the NW extension can also be used for that. Their primary purpose is to deal with networks (i.e., turtles and links) but they won't complain if you have only turtles to save and restore.
Edit:
Here is a full example using runresult:
breed [squares square]
breed [circles circle]
to save-and-restore-breeds
clear-all
create-squares 2
create-circles 2
if file-exists? "test" [ file-delete "test" ]
; save agents:
file-open "test"
file-write count turtles
ask turtles [ file-write (word breed) ]
file-close
clear-all
; restore agents:
file-open "test"
let n file-read
crt n [
let breed-as-string file-read
set breed runresult breed-as-string
]
file-close
show [ breed ] of turtles
end
I'm trying to search across a large array of textual files in Mathematica 8 (12k+). So far, I've been able to plot the sheer numbers of times that a word appears (i.e. the word "love" appears 5,000 times across those 12k files). However, I'm running into difficulty determining the number of files in which "love" appears once - which might only be in 1,000 files, with it repeating several times in others.
I'm finding the documentation WRT FindList, streams, RecordSeparators, etc. a bit murky. Is there a way to set it up so it finds an incidence of a term once in a file and then moves onto the next?
Example of filelist:
{"89001.txt", "89002.txt", "89003.txt", "89004.txt", "89005.txt", "89006.txt", "89007.txt", "89008.txt", "89009.txt", "89010.txt", "89011.txt", "89012.txt", "89013.txt", "89014.txt", "89015.txt", "89016.txt", "89017.txt", "89018.txt", "89019.txt", "89020.txt", "89021.txt", "89022.txt", "89023.txt", "89024.txt"}
The following returns all of the lines with love across every file. Is there a way to return only the first incidence of love in each file before moving onto the next one?
FindList[filelist, "love"]
Thanks so much. This is my first post and I'm largely learning Mathematica through peer/supervisory help, online tutorials, and the documentation.
In addition to Daniel's answer, you also seem to be asking for a list of files where the word only occurs once. To do that, I'd continue to run FindList across all the files
res =FindList[filelist, "love"]
Then, reduce the results to single lines only, via
lines = Select[ res, Length[#]==1& ]
But, this doesn't eliminate the cases where there is more than one occurrence in a single line. To do that, you could use StringCount and only accept instances where it is 1, as follows
Select[ lines, StringCount[ #, RegularExpression[ "\\blove\\b" ] ] == 1& ]
The RegularExpression specifies that "love" must be a distinct word using the word boundary marker (\\b), so that words like "lovely" won't be included.
Edit: It appears that FindList when passed a list of files returns a flattened list, so you can't determine which item goes with which file. For instance, if you have 3 files, and they contain the word "love", 0, 1, and 2 times, respectively, you'd get a list that looked like
{, love, love, love }
which is clearly not useful. To overcome this, you'll have to process each file individually, and that is best done via Map (/#), as follows
res = FindList[#, "love"]& /# filelist
and the rest of the above code works as expected.
But, if you want to associate the results with a file name, you have to change it a little.
res = {#, FindList[#, "love"]}& /# filelist
lines = Select[res,
Length[ #[[2]] ] ==1 && (* <-- Note the use of [[2]] *)
StringCount[ #[[2]], RegularExpression[ "\\blove\\b" ] ] == 1&
]
which returns a list of the form
{ {filename, { "string with love in it" },
{filename, { "string with love in it" }, ...}
To extract the file names, you simply type lines[[All, 1]].
Note, in order to Select on the properties you wanted, I used Part ([[ ]]) to specify the second element in each datum, and the same goes for extracting the file names.
Help > Documentation Center > FindList item 4:
"FindList[files,text,n]
includes only the first n lines found."
So you could set n to 1.
Daniel Lichtblau