有没有办法自动化类似(几乎重复)的代码并使其像一个函数?

Posted

技术标签:

【中文标题】有没有办法自动化类似(几乎重复)的代码并使其像一个函数?【英文标题】:Is there a way to automate similar (almost repetitive) code and make it like a function? 【发布时间】:2021-07-19 16:04:20 【问题描述】:

这是代码:它可能没有多大意义,但我的问题与语法无关。

基本上...最多有 7 张图像,它以预定义的布局和其他内容排列...我如何使这个重复的、不可扩展的代码更加精简?

im1 = None
im2 = None
im3 = None
im4 = None
im5 = None
im6 = None
im7 = None

if com == 2:
#    cv2.imshow("")
    layout = int(input("Enter layout number: "))
    im1 = im_1()
    im2 = im_2()
    while (im1 == im2):
        print("Invalid")
        im1 = im_1()
        im2 = im_2()
elif com == 3:
#    cv2.imshow("")
    layout = int(input("Enter layout number: "))
    im1 = im_1()
    im2 = im_2()
    im3 = im_3()
    while (im1 == im2) | (im1 == im3) | (im2 == im3):
        print("Invalid")
        im1 = im_1()
        im2 = im_2()
        im3 = im_3()
elif com == 4:
#    cv2.imshow("")
    layout = int(input("Enter layout number: "))
    im1 = im_1()
    im2 = im_2()
    im3 = im_3()
    im4 = im_4()
    while (im1 == im2) | (im1 == im3) | (im1 == im4) | (im2 == im3) | (im2 == im4) | (im3 == im4):
        print("Invalid")
        im1 = im_1()
        im2 = im_2()
        im3 = im_3()
        im4 = im_4()
elif com == 5:
#    cv2.imshow("Layouts: 5", l5)
    layout = int(input("Enter layout number: "))
    im1 = im_1()
    im2 = im_2()
    im3 = im_3()
    im4 = im_4()
    im5 = im_5()
    while (im1 == im2) | (im1 == im3) | (im1 == im4) | (im1 == im5) | (im2 == im3) | (im2 == im4) | (im2 == im5) | (im3 == im4) | (im3 == im5) | (im4 == im5):
        print("Invalid")
        im1 = im_1()
        im2 = im_2()
        im3 = im_3()
        im4 = im_4()
        im5 = im_5()
elif com == 6:
#    cv2.imshow("")
    layout = int(input("Enter layout number: "))
    im1 = im_1()
    im2 = im_2()
    im3 = im_3()
    im4 = im_4()
    im5 = im_5()
    im6 = im_6()
    while (im1 == im2) | (im1 == im3) | (im1 == im4) | (im1 == im5) | (im1 == im6) | (im2 == im3) | (im2 == im4) | (im2 == im5) | (im2 == im6) | (im3 == im4) | (im3 == im5) | (im3 == im6) | (im4 == im5) | (im4 == im6) | (im5 == im6):
        print("Invalid")
        im1 = im_1()
        im2 = im_2()
        im3 = im_3()
        im4 = im_4()
        im5 = im_5()
        im6 = im_6()
elif com == 7:
#    cv2.imshow("")
    layout = int(input("Enter layout number: "))
    im1 = im_1()
    im2 = im_2()
    im3 = im_3()
    im4 = im_4()
    im5 = im_5()
    im6 = im_6()
    im7 = im_7()
    while (im1 == im2) | (im1 == im3) | (im1 == im4) | (im1 == im5) | (im1 == im6) | (im1 == im7) | (im2 == im3) | (im2 == im4) | (im2 == im5) | (im2 == im6) | (im2 == im7) | (im3 == im4) | (im3 == im5) | (im3 == im6) | (im3 == im7) | (im4 == im5) | (im4 == im6) | (im4 == im7) | (im5 == im6) | (im5 == im7) | (im6 == im7):
        print("Invalid")
        im1 = im_1()
        im2 = im_2()
        im3 = im_3()
        im4 = im_4()
        im5 = im_5()
        im6 = im_6()
        im7 = im_7()

这是一个比较图像的计算机视觉代码,但它最多只能工作 7 个,因为我必须事先预先定义图像。 com 实际上是用户输入的,如果它是 com 大于 7。

另外,如果您看到的话,它只在 7 点之前有效,因为图像比较没有针对 >7 进行硬编码。但是com = n 的逻辑很容易硬编码,但很费力。有没有办法为 n 个图像/术语制作此代码,其中它定义了变量的确切数量,并在 com = n 的比较/布局部分中自我纠正?

同样,我们可以将其扩展为:

if i != 0:
                if i == 1:
                    anim1 = cv2.imread("anim_1.jpg")
                    border_b = cv2.copyMakeBorder(anim1, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
                    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
                    anim1 = border_w
                if i == 2:
                    anim2 = cv2.imread("anim_2.jpg")
                    border_b = cv2.copyMakeBorder(anim2, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
                    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
                    anim2 = border_w
                if i == 3:
                    anim3 = cv2.imread("anim_3.jpg")
                    border_b = cv2.copyMakeBorder(anim3, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
                    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
                    anim3 = border_w
                if i == 4:
                    anim4 = cv2.imread("anim_4.jpg")
                    border_b = cv2.copyMakeBorder(anim4, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
                    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
                    anim4 = border_w
                if i == 5:
                    anim5 = cv2.imread("anim_5.jpg")
                    border_b = cv2.copyMakeBorder(anim5, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
                    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
                    anim5 = border_w
                if i == 6:
                    anim6 = cv2.imread("anim_6.jpg")
                    border_b = cv2.copyMakeBorder(anim6, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
                    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
                    anim6 = border_w
                if i == 7:
                    anim7 = cv2.imread("anim_7.jpg")
                    border_b = cv2.copyMakeBorder(anim7, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
                    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
                    anim7 = border_w

if com == 2:
    if im1 == 1:
        im1 = anim1
        im2 = anim2
    elif im1 == 2:
        im1 = anim2
        im2 = anim1
elif com == 3:
    if (im1 == 1) | (im1 == 2) | (im1 == 3):
        if im1 == 1:
            im1 = anim1
        elif im1 == 2:
            im1 = anim2
        elif im1 == 3:
            im1 = anim3
    if (im2 == 1) | (im2 == 2) | (im2 == 3):
        if im2 == 1:
            im2 = anim1
        elif im2 == 2:
            im2 = anim2
        elif im2 == 3:
            im2 = anim3
    if (im3 == 1) | (im3 == 2) | (im3 == 3):
        if im3 == 1:
            im3 = anim1
        elif im3 == 2:
            im3 = anim2
        elif im3 == 3:
            im3 = anim3

//skipped till end of 7 because too repetitive.

elif com == 7:
    if (im1 == 1) | (im1 == 2) | (im1 == 3) | (im1 == 4) | (im1 == 5) | (im1 == 6) | (im1 == 7):
        if im1 == 1:
            im1 = anim1
        elif im1 == 2:
            im1 = anim2
        elif im1 == 3:
            im1 = anim3
        elif im1 == 4:
            im1 = anim4
        elif im1 == 5:
            im1 = anim5
        elif im1 == 6:
            im1 = anim6
        elif im1 == 7:
            im1 = anim7
    if (im2 == 1) | (im2 == 2) | (im2 == 3) | (im2 == 4) | (im2 == 5) | (im2 == 6) | (im2 == 7):
        if im2 == 1:
            im2 = anim1
        elif im2 == 2:
            im2 = anim2
        elif im2 == 3:
            im2 = anim3
        elif im2 == 4:
            im2 = anim4
        elif im2 == 5:
            im2 = anim5
        elif im2 == 6:
            im2 = anim6
        elif im2 == 7:
            im2 = anim7
    if (im3 == 1) | (im3 == 2) | (im3 == 3) | (im3 == 4) | (im3 == 5) | (im3 == 6) | (im3 == 7):
        if im3 == 1:
            im3 = anim1
        elif im3 == 2:
            im3 = anim2
        elif im3 == 3:
            im3 = anim3
        elif im3 == 4:
            im3 = anim4
        elif im3 == 5:
            im3 = anim5
        elif im3 == 6:
            im3 = anim6
        elif im3 == 7:
            im3 = anim7
    if (im4 == 1) | (im4 == 2) | (im4 == 3) | (im4 == 4) | (im4 == 5) | (im4 == 6) | (im4 == 7):
        if im4 == 1:
            im4 = anim1
        elif im4 == 2:
            im4 = anim2
        elif im4 == 3:
            im4 = anim3
        elif im4 == 4:
            im4 = anim4
        elif im4 == 5:
            im4 = anim5
        elif im4 == 6:
            im4 = anim6
        elif im4 == 7:
            im4 = anim7
    if (im5 == 1) | (im5 == 2) | (im5 == 3) | (im5 == 4) | (im5 == 5) | (im5 == 6) | (im5 == 7):
        if im5 == 1:
            im5 = anim1
        elif im5 == 2:
            im5 = anim2
        elif im5 == 3:
            im5 = anim3
        elif im5 == 4:
            im5 = anim4
        elif im5 == 5:
            im5 = anim5
        elif im5 == 6:
            im5 = anim6
        elif im5 == 7:
            im5 = anim7
    if (im6 == 1) | (im6 == 2) | (im6 == 3) | (im6 == 4) | (im6 == 5) | (im6 == 6) | (im6 == 7):
        if im6 == 1:
            im6 = anim1
        elif im6 == 2:
            im6 = anim2
        elif im6 == 3:
            im6 = anim3
        elif im6 == 4:
            im6 = anim4
        elif im6 == 5:
            im6 = anim5
        elif im6 == 6:
            im6 = anim6
        elif im6 == 7:
            im6 = anim7
    if (im7 == 1) | (im7 == 2) | (im7 == 3) | (im7 == 4) | (im7 == 5) | (im7 == 6) | (im7 == 7):
        if im7 == 1:
            im7 = anim1
        elif im7 == 2:
            im7 = anim2
        elif im7 == 3:
            im7 = anim3
        elif im7 == 4:
            im7 = anim4
        elif im7 == 5:
            im7 = anim5
        elif im7 == 6:
            im7 = anim6
        elif im7 == 7:
            im7 = anim7

tl;dr:我如何使这些不必要的重复代码更加精简?

【问题讨论】:

【参考方案1】:

第一段代码可以使用函数来摆脱令人讨厌的布尔逻辑和数组和循环来摆脱硬编码的变量。

# Replaces im1 - im7
im_values = []
for i in range(7):
    im_values.append(None)

# Map functions to array
im_functions = []
im_functions.append(im_1)
im_functions.append(im_2)
im_functions.append(im_3)
im_functions.append(im_4)
im_functions.append(im_5)
im_functions.append(im_6)
im_functions.append(im_7)

# Checks the long if-tests in your code, a helper function
def any_equal(n):
    for i in range(n-1):
        for j in range(i+1, n):
            if (im_values[i] == im_values[j]):
                return True
    return False

# All hardcoded if tests are replaced with a for loop
#    cv2.imshow("")
layout = int(input("Enter layout number: "))
for i in range(com):
    im_values[i] = im_functions[i]()
    while(any_equal(com)):
        print("Invalid")
        for j in range(com):
            im_values[j] = im_functions[j]()

代码的第二部分看起来可以用一个简单的函数替换。

anims = []
for i in range(7):
    anims.append(None)

def load_anim(img):
    anim = cv2.imread(img)
    border_b = cv2.copyMakeBorder(anim, bt, bt, bt, bt, cv2.BORDER_CONSTANT, value = c_b)
    border_w = cv2.copyMakeBorder(border_b, wt, wt, wt, wt, cv2.BORDER_CONSTANT, value = c_w)
    return border_w

if i != 0:
    anims[i-1] = load_anim(f"anim_i.jpg")

第三部分看起来很相似,只是使用数组和循环,你应该完成它。我把它留给你自己解决,希望不会太难:)

【讨论】:

【参考方案2】:

代码块 1:

看看你是否只能在需要时定义事物

代码块 2:

"anim_"+i+".jpg"

代码块 3:

if im1 == 1) | (im1 == 2) ... | (im1 == 7):

应该是

if im1 <= 7:

对于长 elif 链,使用列表

Anim = [anim0, anim1, anim2]
im1 = Anim[0]

我认为在创建大型项目之前学习更多基础知识会节省时间

# example code 

TmpLayout1 = [[1,0],[0,1]]
TmpLayout2 = [[0,1],[0,1]]
ImageLayouts = [TmpLayout1, TmpLayout2]

【讨论】:

是的,但主要是它仍然需要硬编码......有没有办法创建某种映射框架? 我不确定您的意思,但是您应该能够使用数组并对其进行操作,而无需对任何内容进行硬编码。如果您在布局中排列图像,请将不同的布局存储在数组中,然后根据这些布局放置图像。从我所看到的情况来看,我假设您使用 if 语句对布局进行了硬编码。

以上是关于有没有办法自动化类似(几乎重复)的代码并使其像一个函数?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法打开相机并在屏幕上查看它并使其无法拍照或录制视频。

有没有办法在 lambda 表达式树中使用“动态”?

Laravel 8 - MS SQL - 查询生成器 - 使用 DB Raw。尝试使代码正确,使其像工作的 MSSQL 代码一样工作

创建 ViewController 并使其可下载

iOS 如何手动调整 UIImageView 使其像按钮一样?

如何添加视频元素并使其在启用声音的情况下自动播放