Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 5, 2009 16:46:47

UsCr
От:
Зарегистрирован: 2009-11-04
Сообщения: 216
Репутация: +  0  -
Профиль   Отправить e-mail  

UnboundLocalError

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 среди которых есть двоеточие.
а) Получить все символы расположенные до первого двоеточия включительно.
б) Получить все символы расположенные после первого двоеточия.
в) Получить все символы, расположенные между первым и вторым двоеточием. Если второго двоеточия нет, то получить все символы, расположенные после единственного имеющегося двоеточия.

Впрочем, остальное уже совсем просто.
Ещё раз благодарю за помощь.



Офлайн

#2 Ноя. 5, 2009 17:37:43

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

UnboundLocalError

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

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

Но на самом деле, это только часть задачи.
Предлагаю сделать сначала эту часть, чтобы вы ощутили мощь языка.
Потом, если захотите, посмотрим на остальное.



Офлайн

#3 Ноя. 6, 2009 10:53:57

UsCr
От:
Зарегистрирован: 2009-11-04
Сообщения: 216
Репутация: +  0  -
Профиль   Отправить e-mail  

UnboundLocalError

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)
Похоже?



Отредактировано (Ноя. 6, 2009 10:54:29)

Офлайн

#4 Ноя. 6, 2009 11:20:08

Dimka665
От:
Зарегистрирован: 2008-09-19
Сообщения: 177
Репутация: +  0  -
Профиль   Отправить e-mail  

UnboundLocalError

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)



Офлайн

#5 Ноя. 6, 2009 11:56:32

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

UnboundLocalError

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

С этим куском вроде все. Теперь, если хотите, можете сделать задачу целиком и показать здесь,
учитывая вышесказанные замечания.



Отредактировано (Ноя. 6, 2009 12:15:39)

Офлайн

#6 Ноя. 6, 2009 13:39:11

UsCr
От:
Зарегистрирован: 2009-11-04
Сообщения: 216
Репутация: +  0  -
Профиль   Отправить e-mail  

UnboundLocalError

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)



Офлайн

#7 Ноя. 6, 2009 14:11:14

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

UnboundLocalError

UsCr
if KolSymb > 147: KolSymb = 147
Так совсем плохо. Но даже if KolSymb > len(string.letters) мне кажется не очень хорошим решением.
Лучше замените random.sample на однострочный list comprehension на основе random.choice.



Офлайн

#8 Ноя. 6, 2009 15:30:56

UsCr
От:
Зарегистрирован: 2009-11-04
Сообщения: 216
Репутация: +  0  -
Профиль   Отправить e-mail  

UnboundLocalError

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) - не очень хорошо?



Офлайн

#9 Ноя. 6, 2009 18:14:26

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

UnboundLocalError

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, а ему вернется список другой длины. Разве это хорошо?



Отредактировано (Ноя. 6, 2009 18:20:39)

Офлайн

#10 Ноя. 6, 2009 21:26:50

UsCr
От:
Зарегистрирован: 2009-11-04
Сообщения: 216
Репутация: +  0  -
Профиль   Отправить e-mail  

UnboundLocalError

Напомню условие задачи:
Даны натуральное число 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]
Я знаю, что это синтаксис еррор. Я просто пытаюсь обьяснить, о чём я
говорю. Может быть выловить исключение? Или есть стандартные способы?



Отредактировано (Ноя. 6, 2009 21:31:45)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version