通过类内的For循环与linspace进行迭代

时间:2018-11-16 23:04:32

标签: python python-3.x class numpy for-loop

我创建了一个class capacity,它通过对x迭代值for-loop进行一些计算。计算过程没有错。当此条件匹配时,我只需要打破或停止方程式。

self.Nrd= Ned

要获得上述结果,我创建以下条件,

e=float(Nrd)-Ned
if e>= 0 and e<=1:
    break

但这并不能产生令人满意的令人满意的结果,更好的说法是不能真正正常地工作。

希望您能在达到Nrd = Ned条件时停止方程式。

第二个问题,我并没有真正使用__str__方法得到任何回报。值如何返回?

代码:

import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets

class capacity:
    def __init__(self,b,h,y,ecu,cb,ct,fyd,fcd,Esd,Ned):
        d = h - cb
        ds = ct
        Ast = int(3.1416/4*(y)**2*6.67)
        Asb = int(3.1416/4*(y)**2*6.67)

        for x in np.linspace(1,h,10000):

            esc=ecu/x*(ds-x)
            es=ecu/x*(d-x)

            sisc=Esd*esc
            sis=min(Esd*es,fyd)

            if sisc <= -fyd:
                sisc=-fyd
            elif sisc >= -fyd and sisc < 0:
                sisc= sisc
            else:
                sisc=min(sisc,fyd)

            self.Nrd=int((0.8*x*b*fcd+Ast*sisc-Asb*sis)/1000)
            self.Mrd=(0.8*x*b*fcd*(h/2-0.4*x)+Ast*sisc*(h/2-ds)+Asb*sis*(d-h/2))/1000000

            self.x = x
            e=float(Nrd)-Ned

            if e>= 0 and e<=1:
                break
            if x==h and Nrd != Ned:
                print('Errors','Compression over whole section', sep=' ') 
                app = QtWidgets.QApplication([])
                error_dialog = QtWidgets.QErrorMessage()
                error_dialog.showMessage('Increase size of column, compressed reinforced column!!')
                app.exec_()

    def __str__(self):
        return print(self.x , self.Nrd, self.Mrd)

foo = capacity(b= 300,h=300,y=12,ecu= 0.0035,cb=35,ct=35,fyd=435,fcd=20,Esd=2e5,Ned=1000)

感谢您的帮助,我们欢迎您改进代码。谢谢

代码更新:

根据上面代码的最近参数,我设法定义了一个函数来进行计算,但是我想问的问题是,如何在python中将其实现为一个类。通过功能获得与显示相同的打印。

def capacity(b,h,y,ecu,cb,ct,fyd,fcd,Esd,Ned):
    d = h - cb
    ds = ct
    Ast = int(3.1416/4*(y)**2*6.67)
    Asb = int(3.1416/4*(y)**2*6.67)

    for x in np.linspace(1,h,10000):

        try:
            esc=ecu/x*(ds-x)
            es=ecu/x*(d-x)
        except (ZeroDivisionError, RuntimeWarning):
            esc = 0
            es =  0

        sisc=Esd*esc
        sis=min(Esd*es,fyd)

        if sisc <= -fyd:
                    sisc=fyd
        elif sisc >= -fyd and sisc < 0:
            sisc= sisc
        else:
            sisc=min(sisc,fyd)


        Nrd=int((0.8*x*b*fcd+Ast*sisc-Asb*sis)/1000)
        Mrd=(0.8*x*b*fcd*(h/2-0.4*x)+Ast*sisc*(h/2-ds)+Asb*sis*(d-h/2))/1000000

        e=float(Nrd)-float(Ned)

        if e>= 0 and e<=0.5:
            return print('\n','x value:', x,'\n' ,'Normalforce: ', Nrd,'\n','Moment capacity :', Mrd,'\n','Bottom steel strain :',es,'\n', 
                         'Top steel strain :', esc,'\n', 'Bottom steel stress :', sisc,'\n','Top steel stress :' ,sis )
            break
        if x==h and Nrd != Ned:
            print('Errors','Tryk over hele tværsnit', sep=' ') 
            app = QtWidgets.QApplication([])
            error_dialog = QtWidgets.QErrorMessage()
            error_dialog.showMessage('Increase size of column, compressed reinforced column!!')
            app.exec_()

            return print(x, Nrd, Mrd)


foo = Capacity(b= 300,h=250,y=12,ecu= 0.0035,cb=50,ct=50,fyd=435,fcd=20,Esd=2e5,Ned=800)

结果:

enter image description here

2 个答案:

答案 0 :(得分:1)

您可能正在寻找类似波纹管的东西,创建空的类attrs并调用将其填充为__init__的类的类方法,然后可以使用__str__的重载来得到您想要的输出。 f弦也可能更干净。 (我没有时间收集您的代码并对其进行测试,因此您可能需要进行一些按摩)

import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets

class Capacity():
    def __init__(self,b,h,y,ecu,cb,ct,fyd,fcd,Esd,Ned):
        self.filename = b

        self.x_value = None
        self.nrm_frc = None
        self.mom_cap = None
        self.bsstress = None
        self.tsstress = None
        self.bsstrain = None
        self.tsstrain = None
        self.parse_file(b,h,y,ecu,cb,ct,fyd,fcd,Esd,Ned)

    def parse_file(self,b,h,y,ecu,cb,ct,fyd,fcd,Esd,Ned):
        #all the code for calculation where:
        self.x_value = 'value'
        self.nrm_frc = 'value'
        self.mom_cap = 'value'
        self.bsstress = 'value'
        self.tsstress = 'value'
        self.bsstrain = 'value'
        self.tsstrain = 'value'

    def __str__(self):
        return ('\nx value: {0} \nNormalforce: {1} \nMoment capacity : {2} \nBottom steel strain : {3} '
                '\nTop steel strain : {4} \nBottom steel stress :{5} \nTop steel stress : {6}'
                .format(self.x_value, self.nrm_frc, self.mom_cap, self.bsstress, self.tsstress, self.bsstrain, self.tsstrain))


foo = Capacity(b= 300,h=250,y=12,ecu= 0.0035,cb=50,ct=50,fyd=435,fcd=20,Esd=2e5,Ned=800)
print foo

答案 1 :(得分:1)

There's a live version online of the Capacity class from this answer that you can try for yourself

您的代码在正确的轨道上。有很多小东西可以清理(例如,您可以使用for... else构造检查循环是否没有中断)。您还需要正确实现__str__。这是Capacity类的完整工作实现,可以完成所有这些工作:

import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets

class Capacity:
    labels = (
        ('x', 'x value'),
        ('Nrd', 'Normal force'),
        ('Mrd', 'Moment capacity'),
        ('es', 'Bottom steel strain'),
        ('esc', 'Top steel strain'),
        ('sisc', 'Bottom steel stress'),
        ('sis', 'Top steel stress')
    )

    def __init__(self, *args, **kwargs):
        # most recent values of interest
        self.x = None
        self.Nrd = None
        self.Mrd = None
        self.es = None
        self.esc = None
        self.sisc = None
        self.sis = None

        # if any args are passed to init, try to use them to run .check
        if args or kwargs:
            self.check(*args, **kwargs)

    def check(self, b, h, y, ecu, cb, ct, fyd, fcd, Esd, Ned):
        d = h - cb
        ds = ct
        Ast = int(3.1416/4*(y)**2*6.67)
        Asb = int(3.1416/4*(y)**2*6.67)
        Nrd = None

        for x in np.linspace(1,h,10000):
            try:
                esc = ecu/x*(ds-x)
                es = ecu/x*(d-x)
            except (ZeroDivisionError, RuntimeWarning):
                esc = 0
                es = 0

            sisc = Esd*esc
            sis = min(Esd*es,fyd)

            if sisc <= -fyd:
                sisc=fyd
            elif sisc >= -fyd and sisc < 0:
                sisc = sisc
            else:
                sisc = min(sisc,fyd)

            Nrd = int((0.8*x*b*fcd+Ast*sisc-Asb*sis)/1000)
            Mrd = (0.8*x*b*fcd*(h/2-0.4*x)+Ast*sisc*(h/2-ds)+Asb*sis*(d-h/2))/1000000

            # record values of interest for later printing
            self.x = x
            self.Nrd = Nrd
            self.Mrd = Mrd
            self.es = es
            self.esc = esc
            self.sisc = sisc
            self.sis = sis

            if 0 <= (float(Nrd) - Ned) <= 0.5:
                # the return statement breaks the loop
                return True
        else:
            # the else clause executes if the end of the for loop is reached without a break
            if Nrd != Ned:
                print('Errors','Tryk over hele tværsnit', sep=' ')
                print(self)
                app = QtWidgets.QApplication([])
                error_dialog = QtWidgets.QErrorMessage()
                error_dialog.showMessage('Increase size of column, compressed reinforced column!!')
                app.exec_()

            return False

    def __str__(self):
        strs = []
        for attr,label in self.labels:
            # loop through the labels and get the value of the corresponding attribute from self
            val = getattr(self, attr)
            strs.append('{}: {}'.format(label, val))

        # join all the labeled attribute strings with newline characters and return the result
        return '\n'.join(strs)

然后可以像这样使用Capacity类:

capacity = Capacity(b=300, h=300, y=12, ecu=0.0035, cb=35, ct=35, fyd=435, fcd=20, Esd=2e5, Ned=1000)
print(capacity)

它将输出:

x value: 186.3985398539854
Normal force: 1000
Moment capacity: 130.8115324251227
Bottom steel strain: 0.0014758973472997895
Top steel strain: -0.0028428060107339903
Bottom steel stress: 435
Top steel stress: 295.1794694599579