# 1-2_4

Changes:
* Place sympy helper code in external library
* Streamline algebra
* Place common equations in external library
* Move numerical inputs to the top of the document

Ignore:
* Units. Will rely on use of consistent units


# 1-2_3

Changes:
* Separated Table A-17 into an external library. 
* Modified inputs to use consistent units. 
* Displayed governing equations in readable format. 
* Perform all calculations, including algebraic ones, within body of document.


```python
import sympy as sp
sp.init_printing()
P, S, n_d, A, d = sp.symbols("P S n_d A d", real=True)
sigma = sp.symbols(r"\sigma", real=True)

## Knowns
# Solid rod in tension
#P = 500 #[lbf] Load
#S = 24 #[ksi] Material Strength
#n_d = 3.0 #[-] Factor of Safety

## Governing Equations
# Equation for area of circle
A_eq = sp.Eq(A,sp.pi*d**2/4)
display (A_eq)

# Equation for normal stress
sigma_eq = sp.Eq(sigma, P/A)
display(sigma_eq)

#Equation for safety factor
n_d_eq = sp.Eq(n_d, S/sigma)
display(n_d_eq)
```


```python
def redefine(equality, symbol):
    sol = sp.solve(equality, symbol)
    #if len(sol) > 1:
    #    raise Exception(f"solution produces {len(sol)} possible results")
    return sp.Eq(symbol, sol[-1])

def sub_in(target, sub):
    sol = sp.solve((target, sub), (target.lhs, sub.lhs))
    return sp.Eq(target.lhs, sol[0][0])
```


```python
# Perform algebraic manipulations to prepare for substition
A_eq_d = redefine(A_eq, d)
sigma_eq_A = redefine(sigma_eq, A)
n_d_eq_sigma = redefine(n_d_eq, sigma)
display(A_eq_d)
display(sigma_eq_A)
display(n_d_eq_sigma)
```


```python
# Perform substitutions to obtain equation for diameter
A_eq_d = sub_in(A_eq_d, sigma_eq_A)
display(A_eq_d)
A_eq_d = sub_in(A_eq_d, n_d_eq_sigma)
display(A_eq_d)
```


```python
# Solving for ideal diameter
sub_vals = [
    (P, 500), #[lbs] Load
    (S, 24000), #[psi] material strength
    (n_d, 3) #[-] safety factor
]
d_ideal = A_eq_d.subs(sub_vals).evalf()
d_ideal_val = float(d_ideal.rhs)
display(f"Calculated ideal diameter = {d_ideal_val}")
```


    'Calculated ideal diameter = 0.28209479177387814'



```python
# Find nearest standard fractional inch size
import sys
sys.path.append('..')
from DPy.Shigley_Tables.Table_A_17 import Table_A_17
table = Table_A_17()
frac_val = table.nearest_greater(d_ideal_val, units = "inch_frac")
display(f"Nearest fractional value found for {d_ideal_val} is {frac_val}")
```


    'Nearest fractional value found for 0.28209479177387814 is 0.3125'



```python
# Recalculate factor of safety
n_d_eq = redefine(A_eq_d, n_d)
display(n_d_eq)
sub_vals = sub_vals[0:2]+[(d, frac_val)] #[in] diameter of rod
new_n_d = float(n_d_eq.subs(sub_vals).evalf().rhs)
display(f"New safety factor calculated as {new_n_d} for diameter of {frac_val} inches")
```

Reflection

Pros:
* Input units clearly documented
* Reacts to changing input values
* Text outputs react to changing values
* Code for Table_A_17 lookup recycled from elsewhere
* Derivation of solution clearly followable and completely captured within document
* All inputs are first to converted to compatible unit system


Cons:
* Does not react to changing units
* Unit handling is manual and error-prone
* Quite a large document
* Took great effort to write(hopefully it will get easier)
* Define helper functions for sympy equations within body of document. Better to recycle from library.
* Manually defined common functions for area, stress, safety factor

# 1-2_2

Added automated lookup of values from Table A-17. Modified output messages to update numerical values


```python
from math import sqrt, pi

## Knowns
# Solid rod in tension
P = 500 #[lbf] Load
S = 24 #[ksi] Material Strength
n_d = 3.0 #[-] Factor of Safety

## Desired
# d_min - Minimum diameter of solid rod
# Use common sizes in Shigley table A-17
# Calculate new factor of safety

## Solution
d = sqrt((4*P*n_d)/(pi*S*1000)) #[in] optimal diameter which provides specified factor of safety
```


```python
display(f"The optimal calculated value is {d}, which must be fed into Table A-17 and the closest larger value found. A new safety factor will then be recalculated.")
```


    'The optimal calculated value is 0.28209479177387814, which must be fed into Table A-17 and the closest larger value found. A new safety factor will then be recalculated.'



```python
A_17_dec = [0.01, 0.012, 0.016, 0.020, 0.025, 0.032, 0.040, 0.05, 0.06, 0.08, 0.10, 0.12, 0.16, 0.20, 0.24, 0.30, 0.40, 0.50, 0.60, 0.80, 1.00, 1.20, 1.40, 1.60, 1.80, 2.0, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 7.0, 7.5, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0, 18.5, 19.0, 19.5, 20]
for index, value in enumerate(A_17_dec):
    if d<value:
        display(f"Nearest common size found: {A_17_dec[index]}")
        d_closest = A_17_dec[index]
        break 
```


    'Nearest common size found: 0.3'



```python
n_d = (S*1000*pi*d_closest**2)/(4*P)
display(f"Factor of safety calculated to be {n_d} with d= {d_closest}")
```


    'Factor of safety calculated to be 3.3929200658769765 with d= 0.3'


Reflection

Pros:
* Input units clearly documented
* Reacts to changing input values
* Text outputs react to changing values
* No manual lookup neccessary

Cons:
* Equations derived elsewhere, making a double-check quite difficult
* Does not react to changing units
* Difficult to read the equations. As a result, difficult to debug or check units
* Unit handling is manual (like multiplying by 1000 mid-equation) and error-prone
* Requires manual insertion of table A-17 data into code, which is time-consuming and cumbersome.

# 1-2_1

Simple scripting approach similar to what is commonly seen in Matlab.


```python
from math import sqrt, pi

## Knowns
# Solid rod in tension
P = 2000 #[lbf] Load
S = 24 #[ksi] Material Strength
n_d = 3.0 #[-] Factor of Safety

## Desired
# d_min - Minimum diameter of solid rod
# Use common sizes in Shigley table A-17
# Calculate new factor of safety

## Solution
d = sqrt((4*P*n_d)/(pi*S*1000))
display(d)
```

The optimal calculated value is 0.56, which is manually looked up in Table A-17 and the closest larger fractional value is 0.625. Now the new safety factor must be calculated.


```python
n_d = (S*1000*pi*0.625**2)/(4*P)
display(n_d)
```

Conclusion:
The final factor of safety is 3.68 using a 0.625 inch diameter solid rod.

Reflection

Pros:
* Input units clearly documented
* Reacts to changing input values
* Easy to setup and get a quick answer

Cons:
* Equations derived elsewhere, making a double-check quite difficult
* Does not react to changing units
* Difficult to read the equations. As a result, difficult to debug or check units
* Unit handling is manual (like multiplying by 1000 mid-equation) and error-prone
* Modification of input values requires manual lookup of diameter in table A-17 and insertion into final equation.
* Final display of answer does not update numerical answer
* Final display on answer does not provide the context of input values neccessary to understand output.



```python

```

b58344a395d1c3c0ae5ff383d3437da0512471f7
ipynb
Jupyter Notebook
Example 1-2.ipynb
dpetrovykh/Shigley
b72e3ff9fe3fd512f336ca465c53a1fc0f8fc9dd
MIT
Example 1-2.ipynb
dpetrovykh/Shigley
b72e3ff9fe3fd512f336ca465c53a1fc0f8fc9dd
MIT
Example 1-2.ipynb
dpetrovykh/Shigley
b72e3ff9fe3fd512f336ca465c53a1fc0f8fc9dd
MIT
Qwen/Qwen-72B
1. YES
2. YES