Найти - Пользователи
Полная версия: UnboundLocalError
Начало » Python для новичков » UnboundLocalError
1 2 3 4 5
UsCr
Ed
Интересно было бы увидеть ваше решение.
А вот так:
import random
rand = random.randint
randch = random.choice
arr = []

def generate(KolSymb):
def Dvoetoch():
i = rand(2,3)
for j in range(i):
k = rand(0,KolSymb)
arr[k] = ":"
for i in range(KolSymb+1):
arr.append(randch("abcdefghigklmnopqrstuvwxyz"))
Dvoetoch()
print arr
Думаю, можно ещё проще.
Но на самом деле, это только часть задачи. Вся задача звучит так:
Задача №1:
Даны натуральное число n и символы s1, …, sn среди которых есть двоеточие.
а) Получить все символы расположенные до первого двоеточия включительно.
б) Получить все символы расположенные после первого двоеточия.
в) Получить все символы, расположенные между первым и вторым двоеточием. Если второго двоеточия нет, то получить все символы, расположенные после единственного имеющегося двоеточия.

Впрочем, остальное уже совсем просто.
Ещё раз благодарю за помощь.
Ed
UsCr
Думаю, можно ещё проще.
Можно намного проще. И мы это скоро увидим, если хотите.
Итого, рекомендации по коду:
- Внести arr вовнутрь функции generate. Он не нужен наверху.
- Сделать так, чтобы generate возвращала arr. Таким образом она становится более применимой. Печатать то, что она вернет можно наверху. А можно и еще что-нибудь с этим делать.
- Для генерации списка случайных символов использовать random.sample
- Избавиться от функции Dvoetoch, перенести код в generate. В таком виде, как сейчас она только затрудняет чтение и понимание кода.
- Избавиться от переменной i в коде Dvoetoch. Она используется только один раз, нет смысла ее вообще иметь.

Жду результата :)

Но на самом деле, это только часть задачи.
Предлагаю сделать сначала эту часть, чтобы вы ощутили мощь языка.
Потом, если захотите, посмотрим на остальное.
UsCr
Ed
Жду результата
примерно так:
import random
import string
def generate(KolSymb):
arr = random.sample(string.letters,KolSymb)
for i in range(random.randint(1,2)):
arr[random.randint(0,KolSymb)] = ":"
return arr

def go(Kol):
print generate(Kol)
Похоже?
Dimka665
UsCr
Ed
Жду результата
примерно так:
import random
import string
def generate(KolSymb):
arr = random.sample(string.letters,KolSymb)
for i in range(random.randint(1,2)):
arr[random.randint(0,KolSymb)] = ":"
return arr

def go(Kol):
print generate(Kol)
Похоже?
random.sample выдаст ошибку, если KolSymb > len(string.letters)
Ed
Dimka665
примерно так:
Угу, хорошо. Можете сравнить с вашим вариантом в начале этого треда и восхититься :)

Рекомендации по коду:
Я бы сделал from random import randint как минимум. Короче будет, да и быстрее малость.
Если sample не работает как нужно, то либо сделайте проверку, либо не юзайте вообще. Просто так оставлять нельзя.
Если random.randint(0, KolSymb) вернет вам KolSymb, то получите IndexError.

Теперь о стиле.
Читайте здесь: http://www.python.org/dev/peps/pep-0008/ и здесь: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html
Можете поюзать это для проверки вашего стиля: http://www.logilab.org/857

С этим куском вроде все. Теперь, если хотите, можете сделать задачу целиком и показать здесь,
учитывая вышесказанные замечания.
UsCr
Ed
Если sample не работает как нужно, то либо сделайте проверку, либо не юзайте вообще. Просто так оставлять нельзя.
Если random.randint(0, KolSymb) вернет вам KolSymb, то получите IndexError.
import random
import string
def generate(KolSymb):
if KolSymb > 147: KolSymb = 147
arr = random.sample(string.letters,KolSymb)
for i in range(random.randrange(1,2)):
arr[random.randrange(0,KolSymb)] = ":"
return arr
def go(Kol):
print generate(Kol)
Ed
UsCr
if KolSymb > 147: KolSymb = 147
Так совсем плохо. Но даже if KolSymb > len(string.letters) мне кажется не очень хорошим решением.
Лучше замените random.sample на однострочный list comprehension на основе random.choice.
UsCr
Ed
Лучше замените random.sample на однострочный list comprehension на основе random.choice.
Не очень понимаю я о создании генераторов списков…
res = [x for x in xrange(1, 25, 2)]
print res
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23]
Как это работает?..
И почему if KolSymb > 147: KolSymb = 147 - это очень плохо, а if KolSymb > len(string.letters) - не очень хорошо?
Ed
UsCr
Не очень понимаю я о создании генераторов списков…
res = [x for x in xrange(1, 25, 2)]
print res
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23]
Как это работает?
Аналогично вот этому:
res = []
for x in xrange(1, 25, 2):
res.append(x)
print res
.
Просто более короткая и красивая запись, так называемый синтаксический сахар.

И почему if KolSymb > 147: KolSymb = 147 - это очень плохо
Это плохо, потому что непонятно что такое 147. Код менее читабелен.
Если вместо 147 написать len(string.letters), то это становится хотя бы понятно.
Может быть я вас не понял и ваша константа 147 вообще не относится никак к длине string.letters?
Тогда что это?

Кроме того длина string.letters может меняться(гипотетически), зависеть от текущей локали и т.д.
В случае, если она поменяется в меньшую сторону мы получим ту же проблему, что и была - неработающий sample.

, а if KolSymb > len(string.letters) - не очень хорошо?
Не только if KolSymb > len(string.letters), а еще и KolSymb = len(string.letters).
Это плохо, потому что это неявное изменение входных параметров.
Юзер этой функции скажем позовет ее с параметром 1000, а ему вернется список другой длины. Разве это хорошо?
UsCr
Напомню условие задачи:
Даны натуральное число n и символы s1, …, sn среди которых есть двоеточие.
а) Получить все символы расположенные до первого двоеточия включительно.
б) Получить все символы расположенные после первого двоеточия.
в) Получить все символы, расположенные между первым и вторым двоеточием. Если второго двоеточия нет, то получить все символы, расположенные после единственного имеющегося двоеточия.

Итак, вот мой вариант решения первого пункта:
from random import randrange
from string import letters

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

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

return arr

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
  for i in range(random.randrange(2,3)):
arr[random.randrange(0,KolSymb)] = ":"
Как этот кусок “подсластить” я не придумал. По видимому, это не совсем
возможно в данном случае.

Пытался конструкцию:
 for i in range(0,len(arr)):
xarr.append(arr[i])
if arr[i]==":":break
заменить на:

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