我正在开发某种会生成贝司吉他标签的软件(仅使用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
如果有人告诉我这些问题是什么原因以及如何解决这些问题,我将不胜感激
答案 0 :(得分:0)
global
是declares the scope of the variable而不是创建它的语句。如果您想让代码正常工作,则应在generator
函数之前编写此代码:
tab0 = ""
tab1 = ""
tab2 = ""
tab3 = ""
...但是!
这是非常糟糕的做法。另外,您的代码还有另外几个严重的问题,它们不会引起错误,但是会使您的代码非常不清楚并且难以维护。因此,让我们对其进行修复,使您的代码漂亮:)
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(...)
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行!
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. 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。您的生成器仅返回一个选项卡的选项卡。我认为您的生成器代码中存在逻辑错误。我不知道您想产生什么,所以我不会给您任何建议。