【问题标题】:Iteration with linspace through For loop within class通过类内的 For 循环使用 linspace 进行迭代
【发布时间】:2018-11-16 23:04:32
【问题描述】:

我创建了一个class capacity,它通过for-loop 迭代valuex 来进行一些计算。计算过程没有任何问题。当这个条件匹配时,我只需要打破或停止方程。

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)

结果:

【问题讨论】:

  • print() 不返回任何内容。 __str__ 需要返回一个格式化字符串,类似于{}, {}.format(self.Nrd, self.Mrd)`(我省略了x,它不是参数或属性。__init__ 应该设置一些属性,像这样Nrd。定义另一个方法来实际进行计算。进一步考虑,也许你甚至不需要定义一个类;而是定义一个函数。
  • 我和你想的一样定义一个函数并返回值。你是对的,__str__ returns 字符串。但这些值是int。关于x 值我已在上面的代码中修复。 python中是否存在__int__方法?
  • 我不明白您为什么要以这种方式构建中断条件。 Nrd 和 Ned 似乎都是整数。如果 Nrd==Ned: break 有什么问题?
  • 如果 Nrd = Ned : 中断,有时不要停止或中断,例如如果 Ned = 800,Nrd 将达到 800,0023 或 800,1000 不会中断,原因我更喜欢小数,因为 x 值想要准确地说。
  • 当你break 时,设置某种flag 变量,所以很明显你提前退出了。这样你就不必在之后测试x==h

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


【解决方案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

【讨论】:

  • 太好了,您的课堂解决方案非常棒。这正是我正在寻找的。非常感谢。
【解决方案2】:

您可能正在寻找类似下面的内容,创建您的类 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

【讨论】:

  • 完美。事实上,您提供的解决方案既简单又专业,它可以工作并与我的功能集成。非常感谢。
猜你喜欢
  • 2023-02-23
  • 2010-09-11
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 2011-11-02
  • 1970-01-01
相关资源
最近更新 更多