Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: if-else python 3.4  (Прочитано 2524 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн .ubuntufan

  • Активист
  • *
  • Сообщений: 638
    • Просмотр профиля
Re: if-else python 3.4
« Ответ #15 : 20 Сентября 2014, 05:55:11 »
Цитировать
eval - как раз и сделает неявное преобразование.

Неявное преобразование это когда тип одной переменной неявно преобразуется в другой для конкретной операции в зависимости от контекста.
Eval просто выполняет код, никакого неявного преобразования здесь нет. В данном случае ты (как раз наоборот - явно) сразу вводишь тип int т.к. -20, 30, 433232423L - все это форматы записи целочисленных констант. Так же можно ввести 10.7, и результат будет типом float. Он не преобразовывается в процессе работы, он изначально имеет такой тип.


Пользователь решил продолжить мысль 20 Сентября 2014, 05:59:51:
Цитировать
Я больше наелся неявного конвертирования со строками и байтовыми последовательностями (когда там русский юникодом вылезает).

Туда же - неяного преобразрвания строк не существует. В методах decode / encode кодировка явно задается. До тех пор str - набор байт неопределенной кодировки.
« Последнее редактирование: 20 Сентября 2014, 05:59:51 от .ubuntufan »

Оффлайн Sly_tom_cat

  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 12139
  • Xubuntu 22.04
    • Просмотр профиля
    • Github
Re: if-else python 3.4
« Ответ #16 : 20 Сентября 2014, 22:25:20 »
.ubuntufan, если я пишу input в 2.7 и ввожу там число - то для меня ожидаемо, что он вернет число. Но фактически в терминале я ввожу символы (цифр). И вот это (символы цифр в число) и есть преобразование. То что его делает функция у меня не спросив - и есть неявность этого преобразования. Хотя в данном контексте преобразование для меня не только полезно, но и ожидаемо. А вот если я там напишу неверное число (допустим буква в середине) - input вернет строку.  :idiot2: я код программы рассчитывал на число. И ошибка возникнет не на вводе (что было бы логично), а уже там, где будет использована строка на месте где ожидалось число. Т.е. фактическое место возникновения ошибки отнесено от места где произойдет наведенная ошибка.

Теперь про строки.
Допустим я открываю на чтение файл - и добавляю в каждую строку текста дополнительный символ в начало строки (символ задается константой в программе). Куда девать результат в контексте примера - не важно.
И вот тут у меня происходит простое действие: <строка константа> + <строка прочитанная из файла>.
И вот тут происходит ошибка преобразования символов. :idiot2: Я хочу сразу спросить - а кто вообще просил какие-то символы преобразовывать?  >:( >:( - я просил просто сложить две строки....

Но далее выясняется, что складываю то я не две строки. А строку <строка константа> и байтовую последовательность, которой является <строка прочитанная из файла> и вот тут в Py2.7 к массиву байтов будет применен (самим интерпретатором) decode... только вот кодировку для этого decode у меня никто не спросил :idiot2: - Это и произошло неявное преобразование. Или вы считаете оно явное? Но я же не написал в своем коде ни одного decode или encode. Я просто сложил две (как я думал) строки.

Так что позвольте мне с вами не согласится - python 2.7 во множестве мест делает неявные преобразования данных. И часто оно бывает и на руку программисту, но если оказывается не так - то ошибка, которую выдает интерпретатор возникает совсем не там где была ошибка с типом (который был неявно преобразован). Что на деле усложняет диагностику.

Собственно эти косяки и обсуждались активно, когда вырабатывался стандарт Python 3. И в Python 3.x уже просто нельзя сложить байтовый массив со строкой. Как и input - выдает строку символов, а не число (даже если эти символы соответствуют верной записи числа).
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: https://help.ubuntu.ru/wiki/uefiboot

Оффлайн .ubuntufan

  • Активист
  • *
  • Сообщений: 638
    • Просмотр профиля
Re: if-else python 3.4
« Ответ #17 : 21 Сентября 2014, 03:07:50 »
Цитировать
если я там напишу неверное число (допустим буква в середине) - input вернет строку.  :idiot2: я код программы рассчитывал на число. И ошибка возникнет не на вводе (что было бы логично), а уже там, где будет использована строка на месте где ожидалось число. Т.е. фактическое место возникновения ошибки отнесено от места где произойдет наведенная ошибка.

Какая строка, лол.

>>> input()
32321azazaz23213
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    32321azazaz23213
                   ^
SyntaxError: unexpected EOF while parsing
>>>

Eval просто выполняет вводимое выражение.
20 "преобразовывается" в int не потому что происходит неявное преобразование а потому что 20 - формат записи целочисленных констант в коде Python.

https://docs.python.org/2/library/functions.html#eval

>>> x = 1
>>> print eval('x+1')
2

По поводу строк:
Код будет совершенно справедливо выбрасывать эксепшен т.к. однозначно декодировать во всех кодировках можно только ascii диапазон. Во всех других случаях для строк требуется явное указание decode / encode, иначе интерпретатор не дает таким строкам конкатенироваться т.к. определяет выход байт за диапазон ascii.
« Последнее редактирование: 21 Сентября 2014, 03:38:10 от .ubuntufan »

Оффлайн Sly_tom_cat

  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 12139
  • Xubuntu 22.04
    • Просмотр профиля
    • Github
Re: if-else python 3.4
« Ответ #18 : 21 Сентября 2014, 16:44:14 »
.ubuntufan, скажите вы действительно не понимаете, что сложить две строки (а разницы между строкой и байтовым массивом в python 2.7 практически нет) и получить эксепшн преобразования - это нонсенс? :idiot2:

Про eval - вообще не пользовался ни разу - потому и был не прав. Ну с ним, согласен - он не преобразовывает- вычисляет. И неверное число вроде как не ест. Но сути не меняет - ввод идет символов всегда. А возвращается то что сможет съесть eval. Т.е. если ввести те же цифры, но в кавычках - то таки вернет input строку и получаем то о чем я говорил.   
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: https://help.ubuntu.ru/wiki/uefiboot

delovoy

  • Автор темы
  • Гость
Re: if-else python 3.4
« Ответ #19 : 21 Сентября 2014, 17:35:36 »
Все таки остановился на if elif else. Мне показалось удобным. Но есть проблема, см. код:

Код: (python) [Выделить]
print('Пожалуйста, введите число:')
nomer=int(input())
a1start=100
a1stop=100
a2start=200
a2stop=200

if nomer >= a2start and nomer <= a2stop:
   print('====')
   print('True')
   print('====')
   print (a2start, a2stop)

elif nomer >= a1start and nomer <= a1stop:
   print('====')
   print('False')
   print('====')
   print (a1start, a1stop)

.... (много elif, штук 50 вышло. Вместо True около 10ти разных оповещений, в зависимости от диапазона)

else:
   print ('===============')
   print ('Номер не найден')
   print ('===============')

Замечаю глюки, порой ввел номер и окно закрылось, а порой ввел и отобразилась соответствующее оповещение. Никак не могу понять в чем проблема. Код пересмотрел от корки до корки, синтаксис правильный. Есть идеи у кого нибудь?

Вышеуказанный вопрос снят. Запустил скрипт в консоли винды и он отобразил ошибки (вполне в читабельном виде) То есть проблема наблюдалась в том, что указывал не правильный номер и когда проверялось от if до else находились ошибки и консоль закрывалась.

И еще вопрос, например запустил скрипт, выполнил код, скрипт отобразил результат я жмякнул кнопку и скрипт закрылся. А что дописать, чтобы скрипт после того как отобразил результат выполнения команды - перезапустился, то есть вновь отобразил Введите число:
 
« Последнее редактирование: 21 Сентября 2014, 17:52:04 от Delovoy »

yura_n

  • Автор темы
  • Гость
Re: if-else python 3.4
« Ответ #20 : 21 Сентября 2014, 21:16:38 »
И еще вопрос, например запустил скрипт, выполнил код, скрипт отобразил результат я жмякнул кнопку и скрипт закрылся. А что дописать, чтобы скрипт после того как отобразил результат выполнения команды - перезапустился, то есть вновь отобразил Введите число: 
В цикл while код заверните.

Оффлайн Sly_tom_cat

  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 12139
  • Xubuntu 22.04
    • Просмотр профиля
    • Github
Re: if-else python 3.4
« Ответ #21 : 21 Сентября 2014, 22:48:13 »
Delovoy, писать один и тот же код 50 раз - извините это мазахизм. Это меняется на цикл for
Хотите видеть результат и вводить повторно - цикл while, хотя вернее был бы do-until - но его нет в python: заменяется на
Код: (python) [Выделить]
while True:
 ...
 if <условие выхода>: break
Кроме того полезно разделять интерфейсную и функциональную части.

Код: (python) [Выделить]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

ranges = [
    (1, 100),
    (200, 300),
    (600, 800) #, и далее все ваши 50 диапазонов
]

def check_num(num):
   for x in ranges:
       if num >= x[0] and num <= x[1]:
           return True
   return False

while True :
  num = int(input('Пожалуйста, введите число:'))
  print('True' if check_num(num) else 'False')
  ans = input('Повторить (Y/n):')
  if len(ans) >0 :
    if ans.upper() == 'N':
      break


« Последнее редактирование: 21 Сентября 2014, 23:23:16 от Sly_tom_cat »
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: https://help.ubuntu.ru/wiki/uefiboot

delovoy

  • Автор темы
  • Гость
Re: if-else python 3.4
« Ответ #22 : 21 Сентября 2014, 22:51:33 »
Delovoy, писать один и тот же код 50 раз - извините это мазахизм. Это меняется на цикл for
Хотите видеть результат и вводить повторно - цикл while (хотя вернее был бы do-until - но его нет в python)
Кроме того полезно разделять интерфейсную и функциональную части.


Есть предложение написать код так, чтобы в зависимости от комбинации цифр выводило соответствующее оповещение? Оповещений порядка 10 штук. Если есть, поделитесь. 

Знаю, что можно сделать проще, но не знаю как. Сделал так насколько хватило знаний, то есть вообще никак, 43 кило байта кода)))

Пользователь решил продолжить мысль [time]21 Сентябрь 2014, 23:03:04[/time]:
Код: (python) [Выделить]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

ranges = [
    (1, 100),
    (200, 300),
    (600, 800) #, и далее все ваши 50 диапазонов
]

def check_num(num):
   for x in ranges:
       if num >= x[0] and num <= x[1]:
           return True
   return False

while True :
  num = int(input('Пожалуйста, введите число:'))
  print('True' if check_num(num) else 'False')
  ans = input('Повторить (Y/n):')
  if len(ans) >0 :
    if ans.upper() == 'N':
      break


Каким образом манипулировать оповещением определенных диапазонов? Если например для определенного диапазона, которому нужно дать отличное от других оповещение?

зы, в питоне нуль полный, наберитесь терпения  :-[
« Последнее редактирование: 21 Сентября 2014, 23:04:18 от Delovoy »

Оффлайн Sly_tom_cat

  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 12139
  • Xubuntu 22.04
    • Просмотр профиля
    • Github
Re: if-else python 3.4
« Ответ #23 : 21 Сентября 2014, 23:06:35 »
Delovoy, как связаны оповещения и диапазоны?

Можно в принципе записать под каждый диапазон сообщение

Код: (python) [Выделить]
#!/usr/bin/env python3

ranges = [
    (1, 100, 'msg1'),
    (200, 300, 'msg2'),
    (600, 800, 'msg3') #, и далее все ваши 50 диапазонов
]

def check_num(num):
   for x in ranges:
       if num >= x[0] and num <= x[1]:
           return x[2]
   return 'False'

while True :
  num = int(input('Пожалуйста, введите число:'))
  print(check_num(num))
  ans = input('Повторить (Y/n):')
  if len(ans) >0 :
    if ans.upper() == 'N':
      break
« Последнее редактирование: 21 Сентября 2014, 23:10:20 от Sly_tom_cat »
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: https://help.ubuntu.ru/wiki/uefiboot

delovoy

  • Автор темы
  • Гость
Re: if-else python 3.4
« Ответ #24 : 21 Сентября 2014, 23:12:02 »
Delovoy, как связаны оповещения и диапазоны?

Можно в принципе записать под каждый диапазон сообщение

Код: (python) [Выделить]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

ranges = [
    (1, 100, 'msg1'),
    (200, 300, 'msg2'),
    (600, 800, 'msg3') #, и далее все ваши 50 диапазонов
]

def check_num(num):
   for x in ranges:
       if num >= x[0] and num <= x[1]:
           return x[2]
   return 'False'

while True :
  num = int(input('Пожалуйста, введите число:'))
  print(check_num(num))
  ans = input('Повторить (Y/n):')
  if len(ans) >0 :
    if ans.upper() == 'N':
      break


Это упростит задачу. Огромное Спасибо. Я Попробую так. На первый взгляд, так гораздо проще (пол дня убил, чтобы в else все написать =))

Диапазоны вообще никак не связаны. Например номер который начинается на 215, может заканчиваться 1234 и будет одно оповещение, а если заканчивается на 4321 то другое.

Попробовал, это самое оно! Благодарю)))

Да я действительно похожу был занят маразмом, сначала 50 диапазонам присвоил переменные, а потом всунул их в if-else (деревенский способ какой то)  :2funny:

Пользователь решил продолжить мысль 21 Сентября 2014, 23:24:07:
Завтра напишу новый скрипт и скажу сколько байт сэкономили на жестком диске))))
« Последнее редактирование: 21 Сентября 2014, 23:24:07 от Delovoy »

Оффлайн Sly_tom_cat

  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 12139
  • Xubuntu 22.04
    • Просмотр профиля
    • Github
Re: if-else python 3.4
« Ответ #25 : 21 Сентября 2014, 23:29:32 »
Диапазоны вообще никак не связаны. Например номер который начинается на 215, может заканчиваться 1234 и будет одно оповещение, а если заканчивается на 4321 то другое.
У вас проблемы в логике -  вашем примере на самом деле два диапазона 215 - 1234 (сообщение 1) и 1235 - 4321 (сообщение 2).

Сообщение 2 никогда не может быть выдано для диапазона 215 - 1234 т.к. там всегда будет выдаваться сообщение 1
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: https://help.ubuntu.ru/wiki/uefiboot

delovoy

  • Автор темы
  • Гость
Re: if-else python 3.4
« Ответ #26 : 21 Сентября 2014, 23:53:27 »
Диапазоны вообще никак не связаны. Например номер который начинается на 215, может заканчиваться 1234 и будет одно оповещение, а если заканчивается на 4321 то другое.
У вас проблемы в логике -  вашем примере на самом деле два диапазона 215 - 1234 (сообщение 1) и 1235 - 4321 (сообщение 2).

Сообщение 2 никогда не может быть выдано для диапазона 215 - 1234 т.к. там всегда будет выдаваться сообщение 1

Диапазон начинающийся с 215 заканчивается на 1234 (Включите логику, начинается с 0000) А диапазон заканчивающийся на 4321 начинается с 1235. Или у вас проблемы с логикой или невнимательностью? Или не научились гадать на кофейной гуще?)))

Оффлайн Sly_tom_cat

  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 12139
  • Xubuntu 22.04
    • Просмотр профиля
    • Github
Re: if-else python 3.4
« Ответ #27 : 22 Сентября 2014, 12:04:02 »
Delovoy, тогда я совсем не понимаю вашу фразу: "Например номер который начинается на 215, может заканчиваться 1234 и будет одно оповещение, а если заканчивается на 4321 то другое."

У меня вроде все в порядке с русским языком (родной) и такое описание я однозначно интерпретирую как указание на два (пересекающихся) диапазона 215 - 1234 и 215 - 4321. Но с вашей схемой расстановки сообщений - фактически делит на два не пересекающихся. В чем вы сами и сознаетесь после моего замечания.  :idiot2:

Однако, по мне - это совсем не важно. Даже если задать пересекающиеся диапазоны - то все равно проверка их будет вестись последовательно (если не мудрить с распараллеливанием анализа на несколько потоков) и тот диапазон из перекрывающихся, что будет проверен первым, просто "отъест" от диапазона, который будет проверяться позже. И программа отработает однозначно детерминированно (т.е. разные прогоны кода с одним числом дадут всегда один и тот же результат).
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: https://help.ubuntu.ru/wiki/uefiboot

 

Страница сгенерирована за 0.022 секунд. Запросов: 22.