我该如何解决这些错误?低音吉他tab头发生器

时间:2019-03-24 21:41:46

标签: python

我正在开发某种会生成贝司吉他标签的软件(仅使用4个琴弦和品格0-12 i 尝试在任何地方定义这些全局变量,但这没有用。 还有关于函数校准的错误是什么?

错误:

  

回溯(最近通话最近):     在"/home/olaf/Documents/Projects/BassComposer/main.py"行的第69行中输入文件       generator(fret, string)     生成器中的文件“ /home/olaf/Documents/Projects/BassComposer/main.py”,第62行       tab3 += str(fret)   NameError:名称'tab3'未定义

from random import randint

try:
    times =str(int(input("How many notes do you want to be created?\n\n")))
except:
    print("\nInvalid input!\n")

print("\n\nGenerating " + times + " note(s) long bassline\n...\n\n")

startString = randint(0, 3)
startFret = randint(0, 9)

string = startString
fret = startFret

notes = int(times)




def generator(fret, string):
    global tab0
    global tab1
    global tab2
    global tab3
    x = randint(0,11)
    y = randint(0,16)
    if x in range(4, 9):
        if x in range(4, 7) and fret in range(0,11):
            fret += 1
            if x in range(4, 5) and fret in range(0, 11):
                fret += 1
    if x in range(8,11) and fret in range(1,12):
        fret -= 1
        if x in range(10,11) and fret in range(1, 12):
            fret -= 1
    if y in range(11,16):
        if y in range(11, 13) and string in range(0,2):
            string += 1
            if (y == 13) and string in range(0,2):
                string += 1
        if y in range(14, 16) and string in range(1, 3):
            fret -= 1
            if (y==16) and string in range(1, 3):
                fret -= 1
    if string == 0:
        tab0 += str(fret)
        tab1 += " "
        tab2 += " "
        tab3 += " "
    if string == 1:
        tab1 += str(fret)
        tab0 += " "
        tab2 += " "
        tab3 += " "
    if string == 2:
        tab2 += str(fret)
        tab0 += " "
        tab1 += " "
        tab3 += " "
    if string == 3:
        tab3 += str(fret)
        tab0 += " "
        tab1 += " "
        tab2 += " "


for notes in range(0, notes):
    generator(fret, string)
    notes -= 1

如果有人告诉我这些问题是什么原因以及如何解决这些问题,我将不胜感激

1 个答案:

答案 0 :(得分:0)

globaldeclares the scope of the variable而不是创建它的语句。如果您想让代码正常工作,则应在generator函数之前编写此代码:

tab0 = ""
tab1 = ""
tab2 = ""
tab3 = ""

...但是!

这是非常糟糕的做法。另外,您的代码还有另外几个严重的问题,它们不会引起错误,但是会使您的代码非常不清楚并且难以维护。因此,让我们对其进行修复,使您的代码漂亮:)

  1. 全局变量和全局语句是非常不好的做法。您永远无法确定某些全局变量将是正确的并且具有您希望看到的值。在99.9%的情况下,不能选择使用全局变量,而可以用局部变量代替。 如果您确实需要全局语句,则可以使用某种配置文件。您的generator函数更改了四个全局变量的状态,并且不存储结果,我们可以使用以下命令对其进行重写:
def generator(fret, string):
    tab0 = ""
    tab1 = ""
    tab2 = ""
    tab3 = ""
    for notes in range(0, notes):
        # All your another code
    return tab0, tab1, tab2, tab3
...
tab0, tab1, tab2, tab3 = generator(...)
  1. 您有四个逻辑上相等的变量:tab0, tab1, tab2, tab3。如果有人想为6个标签的贝斯吉他运行此代码怎么办?实际上,我们的标签页是一个实体的一部分-标签页...错误...表(抱歉,我不是音乐家)。因此,我们可以将它们组合为一个实体-标签列表!

tab_list = []

有了它,我们的代码:

tab0 += str(fret)
tab1 += " "
tab2 += " "
tab3 += " "

转换为:

tab_list.append((str(fret), None, None, None))(不用担心,我们可以稍后再对其进行转换)

现在我们有了以下代码:

    if string == 0:
        tab_list.append(str(fret), None, None, None)
    if string == 1:
        tab_list.append(None, str(fret), None, None)
    if string == 2:
        tab_list.append(None, None, str(fret), None)
    if string == 3:
        tab_list.append(None, None, None, str(fret))

看到图案了吗? :) str(fret)索引等于string的值!因此,我们将其压缩得更多:

    tabs_to_append = [None, None, None, None]
    tabs_to_append[string] = str(fret)
    tab_list.append(tabs_to_append)

然后将20行代码压缩为3行!

  1. 这部分代码:
for notes in range(0, notes):
    generator(fret, string)
    notes -= 1

代表0..notes,但是!索引名称等于范围限制并在内部更改。这是非常非常不好的做法!在这种情况下它可以工作(这很奇怪),但是在大多数情况下,它将产生许多意外的结果,迫使您每小时进行一次调试。所以我们将其重写为:

for _ in range(0, notes):  # We don't really need this index
  1. 不必要的逻辑:

我将在这段代码中解释这一部分:

1. if x in range(4, 9):
2.         if x in range(4, 7) and fret in range(0,11):
3.             fret += 1
4.             if x in range(4, 5) and fret in range(0, 11):
5.                 fret += 1

您拥有第一个检查x的if语句是4..9。但是在内部,只有一个if语句检查x是4..7。这意味着第一个if语句是无用的,因此我们可以将其删除(或者内部存在逻辑错误)。另外,第2行和第4行的if语句都具有fret in range(0, 11)。我们可以将其移至第一行并获取以下代码:

1. if fret in range(0,11):
2.         if x in range(4, 7):
3.             fret += 1
4.             if x in range(4, 5):
5.                 fret += 1

现在看第4行的if语句。range(4, 5)返回一个项目列表[4]。因此,此行转换为:if x == 4:。现在,我们终于可以更改代码块了:

1. if fret in range(0,11):
2.       if x in range(5, 7):
3.           fret += 1
4.       elif x == 4:
5.           fret += 2

您可以转换其他逻辑代码块。我敢肯定它将简化很多(甚至可以与我们现在重写的块合并)。

最后我们有了新程序:

from random import randint

try:
    times = int(input("How many notes do you want to be created?\n\n"))
except:
    print("\nInvalid input!\n")

print("\n\nGenerating " + str(times) + " note(s) long bassline\n...\n\n")

startString = randint(0, 3)
startFret = randint(0, 9)


def generator(startFret, startString, times):
    string = startString
    fret = startFret
    tab_list = []

    for _ in range(times):
        x = randint(0, 11)
        y = randint(0, 16)

        # Transformed
        if fret in range(0,11):
            if x in range(5, 7):
                fret += 1
            elif x == 4:
                fret += 2

        # Old, removed unnesessary if-statements
        if x in range(8,11) and fret in range(1,12):
            fret -= 1
            if x in range(10,11):
                fret -= 1
        if y in range(11, 13) and string in range(0,2):
            string += 1
            if (y == 13):
                string += 1
        if y in range(14, 16) and string in range(1, 3):
            fret -= 1
            if (y==16):
                fret -= 1

        tabs_to_append = ["_", "_", "_", "_"]
        tabs_to_append[string] = str(fret)
        tab_list.append(tabs_to_append)
    return tab_list

tabs = generator(startFret, startString, times)

# Converts list of time-tabs to strings of tabs-timeline
tabs_str = [
    " ".join([
        tabs[i][j]
         for i in range(len(tabs))
    ])
    for j in range(4)
]
for s in tabs_str:
    print(s)

可以对其进行更多增强(当然,几乎每个程序都可以:)),但是对不起,我感到非常疲倦。我想我长长的数字纸莎草纸对您有所帮助。

P.S。您的生成器仅返回一个选项卡的选项卡。我认为您的生成器代码中存在逻辑错误。我不知道您想产生什么,所以我不会给您任何建议。