how to stop adding 1 to a variable when it reaches 11? - python-3.7

out = 0
def catchoutp2():
global out
x = random.randint(1, 100)
if x > 60:
out += 1
I want to stop adding when out reaches 11

Just add a condition that x > 60 and out < 12. Won't that work?
if x > 60 and out < 12:

Related

Issue trying to sub sample an image

I am trying to resize a given image by sub-sampling it. I am using grayscae iamges.
The way I understand sub-sampling is basically this:
Let's say we have an 5x5 image and we want to resize it by a factor of 2, so the output image will be 3x3.
So if the 5x5 is: (1 2 3 4 5; 6 7 8 9 10; 11 12 13 14 15; 16 17 18 19 20; 21 22 23 24 25)
Then the 3x3 will be: (1 3 5; 11 13 15; 21 23 25)
So if the factor is 2, for the first row we take the first sample and then every second sample and so on. The same for columns.
The code that I wrote for this is:
i = 0;
j = 0;
for row=1:old_rows
if mod((row-1), a) == 0
i = i + 1;
end
for col=1:old_cols
if mod((row-1), a) == 0 && mod((col-1), a) == 0
j = j + 1;
sub_sampled_I(i, j) = I(row, col); % I is the input image
end
end
j = 0;
end
sub_sampled_I = im2uint8(sub_sampled_I);
end
The issue is that the final image has nothing to do with the original. It is just a white image with some black points here and there. What I understand wrong about sub-sampling?

Fibonacci function in matlab / octave

Help with Fibonacci function in octave / matlab.
The Fibonacci pattern is http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html
0 : 0
1 : 1
2 : 1
3 : 2
4 : 3
5 : 5
The function I have works but it skips a one how can I fix this so the function correctly follows the list above? Below is what my function creates.
0 : 0
1 : 1
2 : 2
3 : 3
4 : 5
5 : 8
See function below
function f = rtfib(n)
if n<0
multi=-1; %if neg number store neg in multi variable
n=abs(n); %if neg make pos
else
multi=1;
end
if (n == 0)
f = 0;
elseif (n==1)
f=1;
elseif (n == 2)
f = 2;
else
fOld = 2;
fOlder = 1;
for i = 3 : n
f = fOld + fOlder;
fOlder = fOld;
fOld = f;
end
end
f=f*multi; %put sign back
end
Ps: I'm using octave 4.0 which is similar to matlab
Original code found from
Create faster Fibonacci function for n > 100 in MATLAB / octave
The function you provided assumes the 3rd item of the 0-starting Fibonacci sequence is 2, and that is wrong. Just change that.
function f = rtfib(n)
if n<0
multi=-1; %if neg number store neg in multi variable
n=abs(n); %if neg make pos
else
multi=1;
end
if (n == 0)
f = 0;
elseif (n==1)
f=1;
elseif (n == 2)
f = 1; % its 1
else
fOld = 1; % 1 again.
fOlder = 1;
for i = 3 : n
f = fOld + fOlder;
fOlder = fOld;
fOld = f;
end
end
f=f*multi; %put sign back
end
Now it works:
for ii=0:15
r(ii+1)=rtfib(ii);
end
disp(r)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610

How often does the value w change and how does it change step by step

function [w]=example3(v)
w=[0];
for x =v
for y=v
w(x,y)=x+y;
end
end
end
An example:
v=[5 2];
[w]=example3(v)
0 0 0 0 0
0 4 0 0 7
0 0 0 0 0
0 0 0 0 0
0 7 0 0 10
I have this code and I'm trying to figure out how often does the value change for w. More than that though, I want to , step by step, how the value of w change (maybe just the first few iterations of it).
As suggested by others, you can define a break point where you assign a value to w and see its value.
If you want to do it programmatically, you could add this:
function [w]=example3(v)
w=[0];
idx = 0; % Count number of cycles
for x =v
for y=v
w(x,y)=x+y;
idx = idx + 1;
if idx < 6 % Only display first 5 values
disp(['x: ' num2str(x) ' - y: ' ...
num2str(y) ' - w: ' num2str(w(x,y))])
end
end
end
end

sum of continuous values in matlab

I need to calculate the following in matlab.
EDIT EDIT: I alway have a 16 x 3 matrix. 16 rows and 3 columns.
The 3 columns represent R,G,B and the 16 rows represent points. From 1-16.
An example matrix looks like this:
1 1 1
-1 0 0
0 0 1
1 0 0
-1 0 0
1 0 -1
1 1 1
1 1 1
0 0 0
-1 0 1
1 0 0
0 0 1
1 0 1
0 0 0
0 0 0
1 0 1
Now I need to know are there 11 coherently rows which have min. 1 value ~= 0 in each column?
In the above example the first 8 rows and the last row have in each column min 1 value and are coherently. So this 9 rows are the max coherently rows without a complete zero row between.
Sry that my first post wasn't correct.
I've do that with a really poor for-solution. Is there a faster way (vectorized) to do that?
for i=1:16
for j=0:16
if i+j > 16
value = (i+j)-16;
else
value = i+j;
end
if table(value,1) ~= 0 || table(value,2) ~= 0 || table(value,3) ~= 0
equal = equal + 1;
if equal >= 11
copy(y,x) = 1;
equal = 0;
break;
end
else
equal = 0;
end
end
end
end
And the 16 points are circular. This min the first point and the last point connect.
Thanks for help and sry for the confusing.
This counts the number of coherent rows with at least one none-zero entry without circularity:
B = ~(A==0);
idx = find(sum(B,2) == 0);
result = max([idx;size(A,1)+1] - [0;idx]) - 1;
Now you can check whether result is bigger than 11.
Another way would be:
B = ~(A==0);
C = bwconncomp(sum(B,2)>0);
num = cellfun(#numel,C.PixelIdxList);
result = max(num);
EDIT 2: To account for circularity, i.e. rows at the beginning and the end should be counted as coherent, you could do
B = ~(A==0);
idx = find(sum(B,2) == 0);
result = max([idx;size(A,1)+idx;size(A,1)+1] - [0;idx;size(A,1)+idx]) - 1;
EDIT: I edited the result-line in the first solution according to Knedlsepp's comments.
This is a somewhat clunky solution, but it should give a solution at least if the matrix isn't too big. If you call your matrix m try the following line of code:
log2(max([cumprod(2*logical(m),2),ones(size(m,1),1)],[],2))
I hope this helps!
EDIT:
Now that it is clear what is ment by the question, here's an answer that should work:
find(~[m(:,1)|m(:,2)|m(:,3);0],1)-1 >= 11

Using Iteration in Battle'tanks' Simulation MATLAB

Round three: Jessica vs Battletanks
**tl;dr:
Right now, I need help making my dimensions match. My function flags me at "if attacked == 0"
What I am trying to make it do is read if the value at that location is a zero or not. If it's a zero, then there is no ship there, so it's a 'miss'. If there is a number there (4, 3,2 or 1) then it's a hit.
Basically what I need to do for this next problem is figure out how to write a function that simulates a game of battletanks (or battleship).
http://en.wikipedia.org/wiki/Battleship_(game) in case you've never played
In this function, I feed in three inputs: two arrays of tank locations (so player1 and player2) and a string of the moves made (they are all separated by a space). The field is an 8x8 array and the moves are indicated by strings such as 'A7 H6' etc etc. A7 means to hit the spot at column 1, row 6. 'H6' means to hit column 8, row 6. I have to reflect that in my function.
What I need to output is: the array of the victor's tanks, a vector that details the winner's hits(in order they were made) and a vector displaying the winner (or the string 'Cease Fire!')
function[winner_field, winner_hits, tanks_destroyed] = battleTanks(player1_tanks, player2_tanks, battle_str)
There are four types of tanks in the game:
Heavy tanks are represented by the number '4' and are 3x2
Medium tanks are represented by the number '3' are are 2x2
Light tanks are represented by the number '1' are a 2x1
Tank destroyers are represented by the number '2' and are 3x1
Empty spaces are represented by a '0'
Note:Tanks can be aligned vertically or horizontally
The first player always makes the first move, and it alternates
Not all tanks have to be played, however if you only play one tank and it gets destroyed, you lose
I need to keep track of the order where ships get hit, and then which ones get destroyed
You can make the same move over again
In my output arrays, any place where a tank has been hit but not destroyed should be represented by a 0. So there may be "jagged tanks"
How to win:
If a player destroys all of the player's tanks, they win
If neither side has lost all their tanks after all moves have been played, the winner is determined by the number of hits scored on the enemy fleet (NOT the number of tanks they destroyed).
There can be a tie, in which case In the event of this, the outputs of the function will become the secondary outputs 1) the 1st players final 8x8 array, 2) the 2nd players final 8x8 array, and 3) a string, 'Cease fire!'.
I apologize in advance for the length of the question, and my code.
function[winner_field, winner_hits, tanks_destroyed] = battleTanks(player1_tanks, player2_tanks, battle_str)
player1_moves = mod(battle_str, 2) == 1;
player2_moves = mod(battle_str, 2) == 0; %// Player 2 is the even moves
[player1_moves, player2_moves] = strtok(battle_str);
player2_moves = char(player2_moves);
player1_moves = char(player1_moves);
column = upper(player1_moves(1)) - 64;
row = player1_moves(2) - 48; %// Does the conversion so my funciton knows that A7 means column 1, row 7
attacked = find(player1_moves);
attacked2 = find(player2_moves);
winner_hits = []; %// Empty vector to populate with answers
tanks_destroyed = []; %// Same as above
Counter1 = 0; %// My counter for hits, just in case they both run out of moves before finishing
Counter2 = 0;
Tanks_destroyed1 = 0; %// Counts how many tanks are destroyed by player 1
Tanks_destroyed2 = 0;
heavy_tank1 = find(player1_tanks, 4); %// locates the tanks
heavy_tank2 = find(player2_tanks, 4);
medium_tank1 = find(player1_tanks, 3);
medium_tank2 = find(player2_tanks, 3);
tank_destroyer1 = find(player1_tanks, 2);
tank_destroyer2 = find(player2_tanks, 2);
light_tank1 = find(player1_tanks, 1);
light_tank2 = find(player2_tanks, 1);
if attacked == 0 %// If they hit a zero, it counts as a mis
attack = 'missed';
else
attack = 'hit'; %// if they find a number, they hit a tank
end
hit = 'hit'; %// Translates the string into a variable I can use
missed = 'missed';
if attacked == hit %// Does the counter
Counter1 = Counter1 + 1;
elseif attacked2 == hit
Counter2 = Counter2 + 1;
else
Counter1 = Counter1 + 0;
end
for field = 1:length(player1_tanks)
if heavy_tank1 == 6 %// Counts the destroyed tanks
tank = 'destroyed';
Tanks_destroyed2 = Tanks_destroyed2 + 1;
elseif tank_destroyer1 == 3
tank = 'destroyed';
Tanks_destroyed2 = Tanks_destroyed2 + 1;
elseif medium_tank1 == 4
tank = 'destroyed';
Tanks_destroyed2 = Tanks_destroyed2 + 1;
elseif light_tank1 == 2
tank = 'destroyed';
Tanks_destroyed2 = Tanks_destroyed2 + 1;
else
tank = 'missed';
end
end
for field = 1:length(player2_tanks)
if heavy_tank2 == 6
tank = 'destroyed';
Tanks_destroyed1 = Tanks_destroyed1 + 1;
elseif tank_destroyer2 == 3
tank = 'destroyed';
Tanks_destroyed1 = Tanks_destroyed1 + 1;
elseif medium_tank2 == 4
tank = 'destroyed';
Tanks_destroyed1 = Tanks_destroyed1 + 1;
elseif light_tank2 == 2
tank = 'destroyed';
Tanks_destroyed1 = Tanks_destroyed1 + 1;
else
tank = 'missed';
end
end
if Tanks_destroyed1 == player2_tanks %// Determines the winner
winner_field = player1_tanks;
elseif Tanks_destroyed2 == player1_tanks
winner_field = player2_tanks;
elseif Counter1 > Counter2
winner_field = player1_tanks;
elseif Counter2 > Counter1
winner_field = player2_tanks;
else
winner_field = 'Cease Fire!';
end
if winner_field == player1_tanks
winner_hits = hits;
end
end
This code is really killing my wrists, so I apologize for others who wrists may be hurt. Though I am probably over complicating it.
Testcases
[results1, winHits1, winDestroy1] = battleTanks(battleAP1,battleAP2,moveA)
results1 should be the same as resultsA (which is saved in battleTanks.mat)
winHits1 = [1 1 2 2 2 3 3 3 3]
winDestroy1 = [1 2 3]
battleAP1, battleAP2 and moveA are all files include with the HW problem. I'm going to try and access them to get out their information.
So what I need help with basically is figuring out how to format my output statements and making the function realize that A = column 1.
battleAP1:
0 0 0 0 0 0 0 0
0 0 0 3 3 0 0 0
0 2 0 3 3 0 0 0
0 2 0 4 4 4 0 0
0 2 0 4 4 4 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0
battleAP2
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 3 3 0
0 0 4 4 0 3 3 0
0 0 4 4 0 0 0 0
0 0 4 4 2 2 2 0
0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0
MoveA: 'A5 H7 C3 G1 D3 F7 G6 C2 H6 D4 G7 H2 G8 H4 E5 D8 F6 B6 E6 A5 F5 G2 H3'
Regarding your particular question in the comments, if I have an input A7 and I want to convert it to a set of indices, one way to do this is to split it up and then subtract the ASCII offset. Google ASCII table if you don't understand the numbers I'm using. Basically when you do match with a char and a number in matlab, it automatically converts the char to its ASCII number.
input = 'A7';
column = upper(input(1)) - 64; %upper guarantees that my letter will be upper case
row = input(2) - 48;