Volobuev first branch#69
Conversation
…eptember23 into volobuev_first_branch
…eptember23 into volobuev_first_branch
IlyaOrlov
left a comment
There was a problem hiding this comment.
Есть существенные замечания.
…eptember23 into volobuev_first_branch
| j2 = len(st) | ||
| for i in range(0, len(st) - 1): | ||
| for k in range(i + 1, len(st)): | ||
| if int(st[k]) == int(st[i]): |
There was a problem hiding this comment.
Не вижу исправления. int на месте.
There was a problem hiding this comment.
Сразу исправил.
There was a problem hiding this comment.
| bp = alfavit[15] | ||
| s = "" | ||
| for k in range(0, 4): | ||
| if k == 0: |
There was a problem hiding this comment.
Код в стр.29-31, 34-36, 39-41, 43-45 одинаковый. Зачем его столько раз повторять?
There was a problem hiding this comment.
Нет.
Во-первых, данный код выдаёт ошибку, т.к. s1 в стр.34,38,42 не определена.
Во-вторых, весь код в стр.26-46 можно упростить до:
stop_alf = (alfavit[18], alfavit[19], alfavit[14], alfavit[15])
s = ""
for k in range(0, 4):
b = stop_alf[k][1]
s1 = bukv(b, alfavit)
s += str(s1) + " "или даже до
stop_alf = (alfavit[18], alfavit[19], alfavit[14], alfavit[15])
s = ""
for n, b in stop_alf:
s += str(bukv(b, alfavit)) + " "В-третьих, буквы "a"..."z" и так упорядочены по таблице ASCII. Получить порядковый номер каждой буквы можно и без доп. структуры alfavit простым вычитанием порядкового номера "a".
Например, порядковый номер "z":
nz = ord("z") - ord("a") + 1 # получится 26Узнать символ по порядковому номеру тоже просто. Например, номер 5:
b5 = chr(ord("a") + 5 - 1) # получится "e"Операции ord и chr мы проходили на 5-м занятии (примерно 58-я минута записи).
Если всё же удобней работать с алфавитом как списком, имеет смысл сгенерировать его через алгоритм:
alfavit = []
for i in range(1, ord("z") + 1):
b = chr(ord("a") + i - 1)
alfavit.append((i, b))Это более быстрый и гибкий подход. Если заказчик решит нумеровать буквы с 0, а не с 1, захочет проверять прописные буквы, а не строчные, поправить алгоритм гораздо проще, чем переписывать заново всю последовательность букв и цифр.
Прописать конкретные числа, буквы - это допустимо и даже правильно... на начальном этапе решения. Чтоб увидеть и понять закономерность! Но на этом нельзя останавливаться. Как только закономерность становится явной - её стоит заменить алгоритмом. Когда Вы пишете (1, "a"), (2, "b") и т.д. - это уже рутинная, повторяющаяся деятельность. Пусть её выполняет машина. Вам надо просто задать ей алгоритм. То же самое и с повторяющимся кодом:
if k == ...:
b = ...
buk_v(...)
IlyaOrlov
left a comment
There was a problem hiding this comment.
Хорошо, но замечания ещё есть.
| if arg[k] < arg[i]: | ||
| if arg[k] < arg[n]: | ||
| n = k | ||
| arg[i], arg[n] = arg[n], arg[i] |
There was a problem hiding this comment.
А здесь ещё можно повесить проверку if i != n, чтоб не тратить время на самоприсваивание.
There was a problem hiding this comment.
Не совсем понял предложение.
n = i - присвоение необходимо чтобы знать с какого элемента мы начинаем проверку.
n = k - это присвоение необходимо для проверки повторений цикла
на мой взляд код рабочий и минимальный, меньше только мое первое предложение с пузырьковым методом.
There was a problem hiding this comment.
Да, эти присваивания необходимы. Но если внутри цикла for k in range(i+1, len(arg)) n не поменялся (не нашлось меньшего элемента), то незачем делать и перестановку arg[i], arg[n] = arg[n], arg[i].
Т.е. финальный вариант получается такой:
arg = [0, 3, 24, 2, 3, 7]
print(arg)
for i in range(0, len(arg)-1):
n = i
for k in range(i+1, len(arg)):
if arg[k] < arg[n]:
n = k
if n != i:
arg[i], arg[n] = arg[n], arg[i]
print(arg)There was a problem hiding this comment.
Внес изменения, получил это:
[0, 3, 24, 2, 3, 7]
[0, 2, 3, 7, 3, 24]
There was a problem hiding this comment.
There was a problem hiding this comment.
Спасибо, все получилось. Но мой код короче на одну строку.
Или проводиться дополнительная проверка, или дополнительное присваивание.
На скорость это может повлиять?
There was a problem hiding this comment.
Хороший вопрос. Давайте разбираться. Возьмём список из миллиона элементов и рассмотрим крайние случаи.
- Если список отсортирован по возрастанию (а мы сортируем по убыванию). Тогда n всегда будет != i, т.к. во вложенном цикле всегда будет находиться какой-то меньший элемент. Мы получим миллион лишних проверок.
- Если список отсортирован сразу, как нам нужно (по убыванию). Тогда n всегда будет == i, т.к. во вложенном цикле никогда не будет элементов, меньших, чем i-й. Без проверки
if n != i:мы получим миллион лишних перестановок (самоперестановок).
Если элементы в списке генерируются случайным образом по равномерному распределению, то вероятность обоих крайних случаев одинаковая.
Таким образом, перед нами встаёт дилемма: миллион лишних проверок или миллион лишних перестановок. Проверка - операция чтения, перестановка - это две операции записи. Очевидно, проверка выполняется быстрее, чем перестановка. Поэтому из двух зол я бы выбрал меньшее - проверку.
| @@ -0,0 +1,16 @@ | |||
| def zam(t, dik1): | |||
| t2 = list('') | |||
| n = len(t) | |||
There was a problem hiding this comment.
Код в стр.3-8 можно заменить одной строкой: t = t.replace(dik1['дождь'])
Странно только, что пара 'Вчера': 'Завтра' никак не используется.
There was a problem hiding this comment.
Вставил, код дает ошибку. Вчера и завтра не использовал, т.к. тогда нужно еще менять был и будет.
There was a problem hiding this comment.
ОК. Исправляюсь) Вот такой строкой: return t.replace('дождь', dik1['дождь'])
There was a problem hiding this comment.
Но вообще идея была в том, чтоб получить независимое от конкретных значений решение:
Например:
def zam(t, dik1):
for k, v in dik1.items():
t = t.replace(k, v)
return tА всеми заменами управляем только через содержимое словаря. По сути, так работает автозамена в Word, в PyCharm.
There was a problem hiding this comment.
Надо будет потренироваться с показанным решением.
…eptember23 into volobuev_first_branch
…eptember23 into volobuev_first_branch
…eptember23 into volobuev_first_branch
…eptember23 into volobuev_first_branch
| # cls.cvet = new_color | ||
| print(new_color) | ||
| cls.cvet = new_color | ||
| print(cls.cvet) |
There was a problem hiding this comment.
И всё-таки cls.cvet или cls.color?
There was a problem hiding this comment.
Случайно стер код, пришлось восстанавливать. Исправлю.
There was a problem hiding this comment.
Опять нет!
У Вас в стр.3 задан атрибут color = "Зеленый" (который до этого был cvet = "Зеленый").
Его-то и надо здесь вывести, а new_cvet тут не нужен.
Т.е. либо тут выводите print("cls.color"), либо в стр.3 меняете имя атрибута класса обратно на cvet = "Зеленый".
|
|
||
| class Pupil(Man): | ||
| def __init__(self, name, student): | ||
| self._name = name |
There was a problem hiding this comment.
Имеет смысл здесь (вместо self._name = name) вызвать super().__init__(name). Технически, разницы никакой. Но логически, это показывает преемственность Pupil от Man. Т.е. мы явно указываем, что Pupil умеет всё то же, что и Man (в данном случае, прописывать имя при создании экземпляра), + что-то своё.
То же самое применимо и к строке 22.
Т.е., как сейчас сделано - это не ошибка. Но, скажем так, можно придать этому коду дополнительный смысл. Если не понятно, что я имею в виду, пожалуйста, напишите. Попробую объяснить ещё)
There was a problem hiding this comment.
По стр. 16 кажется понятно. Мы как бы дополнительно указали что есть класс Man, и на основе его открыт класс Pupil. По стр. 22 не понятно. Там time.sleep(i) выполнена задержка времени.
There was a problem hiding this comment.
По стр. 22 мы можем явно показать, что solve_task в классе-наследнике это тот же solve_task, что и в родителе + новый функционал для организации ожидания. Т.е. так:
def solve_task(self):
i = random.randint(3, 6)
time.sleep(i)
super().solve_task()Т.е. Pupil подождал немного, а потом напечатал то же, что печатает в таких случаях родитель. При этом мы можем не конкретизировать здесь, что делает в ходе решения задачи родитель.
|
|
||
| class WrapStrToFile: | ||
| def __init__(self): | ||
| self.filepach = tempfile.mktemp() |
There was a problem hiding this comment.
Должен ли атрибут filepach быть доступен вне класса WrapStrToFile?
There was a problem hiding this comment.
В данной задаче нет, т.к. этот файл в папке временных файлов.
There was a problem hiding this comment.
Дело даже не в том, что это временный файл. А в том, что работа с файлом - это всё внутренняя задача класса WrapStrToFile. И обращений вида:
wstf = WrapStrToFile()
print(wstf.filepach)
wstf.filepach = """быть не должно.
Поэтому стоит объявить данный атрибут защищённым (добавить в название нижнее подчеркивание): self._filepach = tempfile.mktemp()
| print(f"На Вашем счету осталось: {atm.deposit1}") | ||
| return | ||
|
|
||
| def batm(self): |
There was a problem hiding this comment.
Вероятно, это должен быть статический метод.
| if j < 0 or j > atm.deposit1: | ||
| break | ||
| else: | ||
| self.deposit1 = self.deposit1 - j |
| # и наборе поддерживаемых операций. | ||
| class Banks: | ||
| def __init__(self, address, deposit1, deposit2): | ||
| self.address = address |
There was a problem hiding this comment.
Все определённые здесь атрибуты стоит сделать защищёнными. Например, deposit1. Его, по-любому, нельзя позволять менять вне банкомата (lst[i].deposit1 = 100500). Только внутри методов банкомата. Но сейчас выглядит так, как будто можно.
| class Atm_ilyinka(Banks): | ||
|
|
||
| # Снятие со счета | ||
| def snytie(self): |
There was a problem hiding this comment.
Этот метод одинаковый у всех банкоматов (вроде бы). Достаточно оставить его только в классе-родителе (Banks).
| return io | ||
|
|
||
| # Пополнение счета | ||
| def popolnenie(self): |
There was a problem hiding this comment.
А чем пополнение (popolnenie) отличается от взноса (vznos)?
IlyaOrlov
left a comment
There was a problem hiding this comment.
Код с банкоматами хорош, но стоит его оптимизировать!

No description provided.