# While loop and plotting help

Trying to graph some basic stress theory graphs. For this one it should graph a square. I was given some sample Matlab code to go off of so i’ve been referencing that.

I’m having a couple issues:

1. the while loop never ends
2. in the if statement python doesn’t like the x(i) and y(i) = sig_a and sig_b. It seems to be ok if I have it switched to sig_a = x(i). Not sure if this is correct and don’t fully understand why if it is.

Here is the MatLab plot, like I said it should just be a square with side lengths double that of S_Y

Thanks for the help!

See code below.

import numpy as np
import matplotlib.pyplot as plt

np.set_printoptions(precision = 2)
np.set_printoptions(suppress = True)

S_Y = 100
x =0
y =0

i = 1
for degree in range (0, 361,1):
h = 1
theta = degree * (np.pi/180)
fail = 1

``````while fail:
sig_a = h* np.cos(theta)
sig_b = h* np.sin(theta)
sig_all = [sig_a, sig_b, 0]
sig_all.sort()
[sig_3, sig_2, sig_1] = sig_all

if sig_1 >= S_Y or sig_3 <= -S_Y:
fail = 0
sig_a = x(i)
sig_b = y(i)
i+=1

h+=1
``````

plt.plot(x, y)

Hi Matt.

The graph you show, that’s not actually the output of your program, is
it? I cannot see how it possibly could be the output. You tell us that
the while loop is an infinite loop, so the program cannot possibly draw
anything at all. Where did the graph come from?

You have this loop:

``````for degree in range (0, 361,1):
``````

Because 360 degrees is mathematically equal to 0 degrees, you actually
plot the equivalent of 0 degrees twice, only separated by 360 points. Is
that intentional?

You can simplify the loop to:

``````for degree in range(360):  # or 361 if you prefer
``````

You then convert the angle in degrees to radians by hand:

``````theta = degree * (np.pi/180)
``````

You can do that more neatly using:

``````# put this line at the top of the program
import math

# and this one inside the loop
``````

You test for a condition:

``````if sig_1 >= S_Y or sig_3 <= -S_Y:
``````

I’m not sure what that is intended to do, but it clearly is never true,
because the `fail` variable never gets set to 0 and the while loop runs
forever.

Since that condition is never true, none of the code in the block under
it is never run.

``````# This block of code never runs.
fail = 0
sig_a = x(i)
sig_b = y(i)
i+=1
``````

Since fail never gets set to 0, the while loop never ends, and you have
an infinite loop.

That also means that i never gets incremented: it is initialised to
zero, and it stays zero, forever. But that probably doesn’t matter,
because you don’t actually use i anywhere.

And then you have the two lines `sig_a = x(i)` and `sig_b = y(i)`, which
never get run, which is good, because they would fail with a TypeError.
The problm is that x and y are initialised to integers 0, and they never
get changed from 0. Integer 0 is not a function, you cannot call it. If
you do, you get this error:

``````>>> x = 0
>>> x(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
``````

It is impossible to say what those two lines of code are supposed to be,
without knowing what the code is supposed to do.

So because the `if` condition is never true, the TypeError never
happens, and the loop runs forever.

Last but not least, because the loop never ends, the last two lines:

``````h += 1
plt.plot(x, y)
``````

never run.

Where did you get this code from? If you can point us to the original
source, maybe we can work out how it is supposed to work, because at the
moment I’m afraid it is too full of errors for me to fix them. Sorry.

Thanks for giving it a shot! I’m pretty new to coding in general and even newer to python so I appreciate you bearing with me. The figure I provided is from a MATLAB version of the code I provided. I basically was trying to modify that code to work in python. The goal is to plot Maximum Normal Stress Theory, effectively a square like the one in the figure.

I’ve provided the actual MATLAB code as its written so you can see what I’ve been trying to modify.

Hopefully it will clear up what I was trying to do and allow you to point me in the right direction.

Again, I appreciate the help!

``````
%%%% Failure Model - Maximum Normal Stress %%%%%

clear all

% Material properties
S_y = 100;                          % Yield Strength (MPa)

i=1;                                % index for angle
for theta = 0:1:360
h = 1;                          % index for hypotenuse of sig_a and sig_b
fail = 1;                       % Set to zero when failure criteria achieved
while fail
sig_a=h*cosd(theta);
sig_b=h*sind(theta);
sig_all=[sig_a sig_b 0];
sig_sort=sort(sig_all);
sig_1=sig_sort(3);          % 1st principal stress
sig_2=sig_sort(2);          % 2nd principal stress
sig_3=sig_sort(1);          % 3rd principal stress

if (sig_1 >= S_y) | (sig_3 <= -S_y)     % Failure criteria for maximum normal stress theory
fail = 0;
x(i)=sig_a;
y(i)=sig_b;
i=i+1;                  % increase angle
end

h=h+1;
end
end

figure(1)
plot(x,y)
title('Maximum Normal Stress')
xlabel('Sigma A')
ylabel('Sigma B')
xL = xlim;
yL = ylim;
line([0 0], yL, 'Color', 'k');  % Add x-axis to the plot
line(xL, [0 0], 'Color', 'k');  % Add y-axis to the plot

``````