Найти - Пользователи
Полная версия: UnboundLocalError
Начало » Python для новичков » UnboundLocalError
1 2 3 4 5
Ed
UsCr
arr = [string.letters[random.randrange(0,len(string.letters))] \
for i in xrange(0,KolSymb)]
По-моему короче и понятнее будет через random.choice, как я предлагал. Попробуйте.

def first(Kol): #Punkt "a"
arr = generate(Kol)
xarr=[]
print arr
if arr[0]==":":print "Array is empty"
else:
for i in range(0,len(arr)):
xarr.append(arr[i])
if arr[i]==":":break

return xarr
Это делается гораздо короче с помощью срезов и index. Пользуйтесь средствами языка. Ваш код похож на код на паскале или cи.
Вынесите из функции first вызов generate. Просто передайте туда список и что искать. Получите функцию, которую потенциально можно использовать еще где-то.

Можно ли прервать генерацию по условию? Нечто вроде:
xarr = [arr[i] for i in range(0,len(arr)) if arr[i]!=":" else:break]
Я знаю, что это синтаксис еррор. Я просто пытаюсь обьяснить, о чём я
говорю. Может быть выловить исключение? Или есть стандартные способы?
Насколько я знаю нет. Но в данном случае это и не нужно.

Обратите внимание на стиль. Посмотрите на те линки, что я давал. В результате у нас должна получиться программа, принимающая длину списка и символ для вставки в качестве параметра командной строки и выводящая сгенеренный список и три списка - ответы на вопросы а, б, в с пояснениями.
UsCr
from random import randrange
from string import letters
from copy import copy

def generate(KolSymb):
arr = [letters[random.randrange(0,len(letters))] \
for i in xrange(0,KolSymb)]

for i in range(randrange(2,3)):
arr[randrange(0,KolSymb)] = ":"

return arr

def search(arr, symb0, symb1 = "", PrintOn = 1):

if symb1 == 0 :
symb1 = ""
PrintOn = 0

BefArr = arr[0:(arr.index(symb0) + 1)] #symbols before symb0 and "symb0"
AftArr = arr[arr.index(symb0):len(arr)] #symdols after symb0
BetArr = [] #symbols between symb0 and symb1
if symb1 != "":
CopyArr = copy(arr)
del CopyArr[0:(CopyArr.index(symb0) + 1)]
try:
BetArr = CopyArr[0:CopyArr.index(symb0)]
except ValueError:
BetArr = CopyArr

if PrintOn:
print "Before \""+symb0+"\" i see this - "+str(BefArr)
print "After \""+symb0+"\" i see this - "+str(AftArr)
print "Between \""+symb0+"\" and "+symb1+" i see this - "+str(BetArr)

else:
TrupleStr = (BefArr, AftArr, BetArr)
return TrupleStr
search принимает список, первый и второй (второй не обязателен) символ для поиска. Кроме всего, имеет параметр, отвечающий за конечный вывод.
Далее все по условию задачи.

Строка if symb1 == 0 then: symb1 = “” PrintOn = 0 предотвращает ошибку при вызове search(arr, “:”, 0), иначе функция думает что symb1 задан как 0, а PrintOn оставляет по умолчанию.
С пивком потянет?
Ed
Разве что с пивком :)
Что, надоело? Можем тогда на этом остановиться, я не настаиваю.
UsCr
Почему надоело? Я жду конструктивной критики. Сейчас например, мне сложно увидеть ошибки в этом варианте. Особенно тяжело пока со стилем. Ещё я не очень знаком с модулями, посему приходиться постоянно ковырять литературу, что отнимает время и не позволяет в полной мере сосредоточиться.
Ed
Хорошо, тогда продолжим. Мне наверное просто показалось.
100% конструктивную критику не обещаю, но постараюсь.

    arr = [letters[random.randrange(0,len(letters))] \
for i in xrange(0,KolSymb)]
Это пробовали переписать на random.choice? Если не получается - скажите, а то я уже третий раз предлагаю, а в ответ - тишина.

def search(arr, symb0, symb1 = "", PrintOn = 1):
Я бы убрал symb1 и PrintOn отсюда. symb1 решает уже другую задачу, а печатать в функциях такого типа - зло.

AftArr = arr[arr.index(symb0):len(arr)]  #symdols after symb0
len(arr) не нужен, конструкция arr вернет вам все до конца списка.

    BetArr = []                              #symbols between symb0 and symb1
if symb1 != "":
CopyArr = copy(arr)
del CopyArr[0:(CopyArr.index(symb0) + 1)]
try:
BetArr = CopyArr[0:CopyArr.index(symb0)]
except ValueError:
BetArr = CopyArr
У вас уже есь AftArr. Просто поработайте с ним. Конструкция symb0 in AftArr вернет вам True если символ там есть, а дальше - опять срезы.

    if PrintOn:    
print "Before \""+symb0+"\" i see this - "+str(BefArr)
print "After \""+symb0+"\" i see this - "+str(AftArr)
print "Between \""+symb0+"\" and "+symb1+" i see this - "+str(BetArr)
Это нужно делать наверху. Функция поиска чего-либо должна искать и возвращать результат. Печатать или что-то еще с этим делать будет решать код, который ее позовет и получит результат.
В той документации, что я вам дал обратите внимание на конструкции типа:
def main(argv):
....
if __name__ == '__main__':
sys.exit(main(sys.argv))
Так оформляется код в программах на Python. Все, что вам нужно, это вынести в функцию main ваш код верхнего уровня(вызов функций поиска, печать результатов) и обеспечить, чтобы она возвращала 0, если все хорошо и коды ошибок, если оные случаются..
Там же можно проверить входные параметры (список argv).

       
else:
TrupleStr = (BefArr, AftArr, BetArr)
return TrupleStr
Зачем здесь TrupleStr? По-моему он только мешает.
UsCr
Ed
    arr = [letters[random.randrange(0,len(letters))] \
for i in xrange(0,KolSymb)]
Это пробовали переписать на random.choice? Если не получается - скажите, а то я уже третий раз предлагаю, а в ответ - тишина.
Я просто не совсем понимаю преимуществ random.choice.
Нечто вроде:
  arr = [random.choice(letters) for i in xrange(0,KolSymb)]
Так? Просто код станет более читаемым?

Ed
       
else:
TrupleStr = (BefArr, AftArr, BetArr)
return TrupleStr
Зачем здесь TrupleStr? По-моему он только мешает.
Ну…Функция возвращает 3 списка. Как иначе?
Ed
UsCr
Так? Просто код станет более читаемым?
Да, и это дорогого стоит. Впрочем может быть он будет и побыстрее, но я имел в виду именно читабельность.

Ну…Функция возвращает 3 списка. Как иначе?
Просто return BefArr, AftArr, BetArr и все.
UsCr
Ed
Просто return BefArr, AftArr, BetArr и все.
О как… Действительно. Я не так понял фразу “в функции может быть только один return”.
UsCr
Такой вот у меня получился код:
from random import choice
from string import letters
from copy import copy

def generate(KolSymb):
arr = [choice(letters) for i in xrange(0,KolSymb)]

for i in xrange(randrange(2,3)):
arr[randrange(0,KolSymb)] = ":"

return arr

def search(arr, symb0, symb1 = ""):

BefArr = arr[:(arr.index(symb0) + 1)] #symbols before symb0
AftArr = arr[(arr.index(symb0)+1):] #symdols after symb0 #symbols between symb0 and symb1
if symb1 != "": #BetArr symbols between symb0 and symb1
if symb1 in AftArr: BetArr = AftArr[:arr.index(symb1)]
else: BetArr = arr[:]
else: BetArr = None
return BefArr, AftArr, BetArr
А вот как применить здесь код
def main(argv):
....
if __name__ == '__main__':
sys.exit(main(sys.argv))
я не совсем понял, а вернее, совсем не понял. Насколько я знаю, такие конструкции применяют в случае, если нужно сделать модуль скриптом. Я ошибаюсь?
Ed
UsCr
О как… Действительно. Я не так понял фразу “в функции может быть только один return”.
Правильно вы ее поняли. Просто конструкция bla, bla1, bla2 не может быть ничем иным, как tuple, поэтому скобки можно не указывать.
А tuple и будет этим самым единственным возвращаемым значением.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB