i'm writing a test in python2.7 and the test method receives two parameters.
#pytest.mark.parametrize("letter", [
"A", "B", "C"])
#pytest.mark.parametrize("number", [
1, 2, 3])
def my_test(letter, number):
if letter == "B" and number == 2:
pytest.skip("redundant")
I need to skip a redundant combination, let's say for example (B, 2). The only "working" solution leads to calling setup_methods which is useless. Is there a more elegant solution to skip the combination without writing additional "if" condition and without accessing setup_method ?
The only option I would see other than your solution is to write down all possible combinations yourself and comment out or remove all redundant ones (this may be a bit more explicit):
#pytest.mark.parametrize("letter,number", [
("A", 1),
("A", 2),
("A", 3),
("B", 1),
# ("B", 2),
("B", 3),
("C", 1),
("C", 2),
("C", 3),
])
def test_foo(letter, number):
assert something...
This way you save yourself the if, but I like your solution in that way that pytest produces a nice output where it tells you which / that a combination was skipped:
============================= test session starts ==============================
collecting ... collected 9 items
stackoverflow.py::test[1-A] PASSED [ 11%]
stackoverflow.py::test[1-B] PASSED [ 22%]
stackoverflow.py::test[1-C] PASSED [ 33%]
stackoverflow.py::test[2-A] PASSED [ 44%]
stackoverflow.py::test[2-B] SKIPPED [ 55%]
Skipped: redundant
stackoverflow.py::test[2-C] PASSED [ 66%]
stackoverflow.py::test[3-A] PASSED [ 77%]
stackoverflow.py::test[3-B] PASSED [ 88%]
stackoverflow.py::test[3-C] PASSED [100%]
========================= 8 passed, 1 skipped in 0.07s =========================
I guess in this case it's a subjective decision. Both options bear their benefits and downsides.
Related
I try to move each agents to its related agents (defined by high trust connection and in my view) if there are any such agents, and else move the agent to one of its neighbours. However, I get the error "FACE expected input to be an agent but got NOBODY instead." and I don't know how to solve it. I think the use != nobody might cause the error. Any suggestions on how to solve this?
This is my code:
breed [ persons a-person ]
undirected-link-breed [ connections connection ]
connections-own [ trust ]
persons-own [ neighbours ]
to setup
clear-all
create-persons 10
[ setxy random-xcor random-ycor ]
setup-connections
reset-ticks
end
to setup-connections
ask persons
[
create-connections-with other persons
[ set trust 0.6 ]
]
end
to go
setNeighbours
movePersons
tick
end
to setNeighbours
ask persons [ set neighbours other persons in-cone 4 360 ]
end
to movePersons
ask persons
[
let highlyRelatedPersons (turtle-set [other-end] of my-out-connections with [trust = 0.6]) in-cone 4 360
let relatedPersons (turtle-set [other-end] of my-out-connections with [trust = 0.6])
ifelse any? highlyRelatedPersons
[
face one-of highlyRelatedPersons
]
[
let weaklyRelatedNeighbour one-of neighbours with [not member? self highlyRelatedPersons] ;select one of my neighbours that is not a highlyRelatedPerson
ifelse weaklyRelatedNeighbour != nobody
[
face weaklyRelatedNeighbour
]
[
face one-of relatedPersons
]
]
]
end
You are correct in what is causing the error
highlyRelatedPersons is an agentset and while an agentset can be empty, an agentset can never be nobody. one-of highlyRelatedPersons however, will be nobody if the agentset is empty, so you could use ifelse (one-of highlyRelatedPersons != nobody).
That said, is easier to just check if the agentset is empty by using any?:
ifelse any? highlyRelatedPersons
Your code also never actually creates any links for highlyRelatedPersons and relatedPersons is always empty. This means that the code will always return false on the first ifelse and move on to the second. Generally most turtles will have neighbours they can face, but sometimes there are none so they try to face one-of relatedPersons, which again causes a crash since relatedPersons is an empty agentset.
Building my first ABM using Netlogo and have a problem involving ifelse statements and how to use them. I'm modelling agents response to flooded properties. The concepts are as follows:
If an agent is flooded, they will consider adopting protective measures (if they haven't already).
If an agent has adopted protective measures, and are flooded, the success of the measure is calculated.
My code is as follows:
to process-property
let $random-flood-number random-float 1
ask properties [
set flood-damage-list-consequent replace-item 1 flood-damage-list-consequent (item 1 flood-damage-list-initial * (1 - PLP-reduction))
set flood-damage-list-consequent replace-item 2 flood-damage-list-consequent (item 2 flood-damage-list-initial * (1 - PLP-reduction))'
ifelse $random-flood-number < probability-flooding
[
set flooded? TRUE
set number-of-times-flooded (number-of-times-flooded + 1)
if plp-adopted? != TRUE [
calculate-adoption-intention
]
]
[
set flooded? FALSE
]
]
ask properties with [plp-adopted? = TRUE] [
plp-reliability-analysis
]
end
to plp-reliability-analysis
if plp-abandoned? = TRUE [stop]
if flooded? = TRUE [
if number-of-times-flooded > 1 [
let plp-reliability-factor 0.77 ;;This variable represents the probability of success that Manual PLP will offer full reduction in damage. Taken from JBA (2012;2014).
ifelse random-float 1 < plp-reliability-factor
[
set plp-deployed-successful? TRUE
set PLP-reduction 0.25
set successful-flood-damage-reduction (sum flood-damage-list-initial * PLP-reduction)
]
[
set plp-deployed-successful? FALSE
set PLP-reduction 0.9
set unsuccessful-flood-damage-reduction (sum flood-damage-list-initial * PLP-reduction)
calculate-abandonment-intention
]
]
]
end
I have written the following code as an error check, which i keep getting:
if flooded? = FALSE and plp-deployed-successful? = TRUE [error["Properties should only deploy PLP when they are flooded"]]
I believe the problem lies in the ifelse statements in "plp-reliability-analysis" procedure. I'm new to Netlogo and am confused as to when to use an 'if' or 'ifelse' statement. If someone could explain and have a look at the above code i'd be very grateful.
Thanks,
David
The difference between if and ifelse is that:
if is used when you want to run some piece of code only under certain conditions
ifelse is used when you want to run some piece of code under some condition and a different piece of code if the condition is not met.
Have a look at this shortened version of your code. Note that I moved the opening bracket to the beginning of the line to line up the start and end of code blocks. I also put end bracket on the same line for very short code blocks, but the bracketing is the same as yours.
to process-property
let $random-flood-number random-float 1
ask properties
[ ifelse $random-flood-number < probability-flooding
[ set flooded? TRUE ]
[ set flooded? FALSE ]
]
ask properties with [plp-adopted? = TRUE]
[ plp-reliability-analysis
]
end
to plp-reliability-analysis
if flooded? = TRUE
[ if number-of-times-flooded > 1
[ let plp-reliability-factor 0.77
ifelse random-float 1 < plp-reliability-factor
[ set plp-deployed-successful? TRUE ]
[ set plp-deployed-successful? FALSE ]
]
]
end
You draw a random number and assign it to the variable $random-flood-number. Then you ask every property agent to compare that number to the value of probability-flooding. However, you never draw a new random number. So if it's true for one property, it will be true for all the properties. Given it is a flood model, that is presumably intentional as all houses are equally affected by flooding.
Imagine that a low number is drawn and they all get flooded. All the ones with plp-adopted? are then sent to the plp-reliability-analysis procedure. For all of them, the variable flooded? is true so the code block is run.
The first line is if number-of-times-flooded > 1. The first time a flood occurs, the number-of-times-flooded is changed from 0 to 1. That will fail the test (did you mean to use >= instead of > ?) and the remainder of the code will not be run. It will simply jump to the end bracket.
[ let plp-reliability-factor 0.77
ifelse random-float 1 < plp-reliability-factor
[ set plp-deployed-successful? TRUE ]
[ set plp-deployed-successful? FALSE ]
]
But for the second and later code, it will run and 77% of the properties will have the plp recorded as successful, and the others set to unsuccessful.
So, how do you end up with some properties having the combination of false flood? and true plp-deployed-successful?.
Now jump forward in time and 2 (or more) floods have occurred. A flood has just happened, so 77% of the properties with plp-adopted? have true plp-deployed-successful? This time, there is not a flood and all properties have flooded? set to false. Those with plp-adopted? are sent to the plp-reliability-analysis procedure. However, flooded? is now false so the code block does not run and they retain their values of plp-deployed-successful? from the previous run through.
A list called ownList2 consists of two parameters. Flockmates are all the neighbours in a given radius of the neighbour. I tried this code in version 6.0. But it doesn't work.
Basically, I want to put a list of equal dimension into a matrix. Is there something wrong I am doing? Or someone could improve the code piece?
ask turtles[set ownList2 (list who sensed)]
;sensed is sensor value of a turtle with respect to the patch.
;ownList2 is like a message of two bytes,
;first byte mentioning the identity of the itself
;second byte mentioning the value of the sensor.
ask turtles[
foreach (list flockmates)
[
i -> set m45 matrix:to-column-list ( list [ownList2] of i )
]
]
Result:
For turtle-0 with neighbours 1, 2, 3:
ownList2 ~ [1 200]
[2 400]
[3 900]
The m43 for turtle-0 should look like
[[1 200][2 400][3 900]]
Thanks for adding that information. Here is a toy example that might do what you need:
extensions [ matrix ]
turtles-own [ ownlist2 sensed m45 ]
to setup
ca
; Setup example turtles as per question
foreach [ 100 200 400 900 ] [
n ->
crt 1 [
while [ any? other turtles-here ] [
move-to one-of neighbors4
]
set sensed n
set ownlist2 ( list who sensed )
]
]
; Get the turtles to create matrices from the ownlists of
; sorted other turtles
ask turtles [
set m45 matrix:from-column-list map [ i -> [ ownlist2] of i ] sort other turtles
]
; Example output:
ask turtle 0 [
print "Turtle 0's m45:"
print matrix:pretty-print-text m45
]
reset-ticks
end
Output example:
Turtle 0's m45:
[[ 1 2 3 ]
[ 200 400 900 ]]
Given the following code:
defmodule Pullapi.Workout do
import Pullapi.Numbers
#moduledoc """
Functions that generate a workout representation
"""
#doc """
Returns a pullup set defined by the number of `max_reps` a user can do, a `percentage`, and the
number of maximum additional or decremented reps, `rep_bound`.
## Examples
iex> Pullapi.Workout.pullup_set(20, 60, 5)
%{"Action" => "Pullups", "Units" => "14"}
"""
#spec pullup_set(integer, integer, integer) :: map()
def pullup_set(max_reps, percentage, rep_bound) do
median = max_reps * (percentage / 100)
unit_range = Pullapi.Numbers.median_range(round(median), rep_bound)
units = Enum.random(unit_range)
%{"Action" => "Pullups", "Units" => "#{units}"}
end
end
The doctest fails with:
1) test doc at Pullapi.Workout.pullup_set/3 (1) (PullapiTest)
test/pullapi_test.exs:4
Doctest failed
code: Pullapi.Workout.pullup_set(20, 60, 5) === %{"Action" => "Pullups", "Units" => "14"}
left: %{"Action" => "Pullups", "Units" => "8"}
stacktrace:
lib/pullapi/workout.ex:13: Pullapi.Workout (module)
Is there a way of specifying that the "Units" value is randomly generated? It looks like I'm following the way Enum.random is doctested
Enum.random's doctest is explicitly setting a seed value for the test, which makes the result of future calls to :rand functions deterministic.
iex(1)> for _ <- 1..10 do
...(1)> :rand.seed(:exsplus, {101, 102, 103})
...(1)> Enum.random([1, 2, 3])
...(1)> end
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
The person who wrote the tests most likely ran the functions once to check what values are returned after those seed values are set and then put them in the doctest. Unless the inner workings of :rand change, those seeds will keep producing the same values, which is good enough for doctests (you can always fix the tests if it breaks in future versions of Erlang).
So, to fix your doctest, you should execute this code once in iex (you can change the seed values if you want):
:rand.seed(:exsplus, {101, 102, 103})
Pullapi.Workout.pullup_set(20, 60, 5)
And then hardcode the returned values in your doctest. Your tests should now pass until Erlang's rand module's internals change.
Following my question yesterday, I was trying to implement the code with filter and length. I think I achieved the filter but now I need the agents to compare their list length with other agent (activities) list. Here is my code:
ask agentes [
set culture-tags n-values 17 [random 2]
set shared-culture (filter [ i -> i = 0 ] culture-tags) ;count 0s and
create shared-culture
]
end
to move-agentes
ask agentes [
let nearest-activity min-one-of (activities) [ distance myself ]
ifelse any? activities in-radius sight-radius with
[ length t-shared-culture = length shared-culture ] ;as many 0s in t-shared-culture (specified later in the setup for activities) as in shared-culture
[ face nearest-activity ]
[ rt random 40
lt random 40
fd 0.3
]
]
Netlogo prints the next error: "ACTIVITIES breed does not own variable SHARED-CULTURE error while activity 176 running SHARED-CULTURE".
I imagine the mistake must be here: [ length t-shared-culture = length shared-culture ] but I don't know how to make both lists to interact.