2015-05-03 4 views
3

Я делаю ООП в Python, и у меня возникают проблемы, когда пользователь вводит кортеж в качестве одного из аргументов. Вот код:Проблема с кортежами

Я пробовал мысли, инициализируя дюйм до 0, помогло бы, но это не сработало. Кортежи также не поддерживают индексирование, поэтому опция также не существует. Я чувствую, что ответ прост, и я просто переусердствовал. Тестовый код, который я использую:

from height import * 
def test(ht): 
    """tests the __str__, __repr__, and to_feet methods for the height 
    Height->None""" 
    #print("In inches: " + str(ht.to_inches())) 
    #print("In feet and inches: " + str(ht.to_feet_and_inches())) 
    print("Convert to string: " + str(ht)) 
    print("Internal representation: " + repr(ht)) 
    print() 
print("Creating ht1: Height(5,6)...") 
ht1 = Height(5,6) 
test(ht1) 
print("Creating ht2: Height(4,13)...") 
ht2 = Height(4,13) 
test(ht2) 
print("Creating ht3: Height(50)...") 
ht3 = Height(50) 
test(ht3) 

Мой код работает, как ожидалось, когда int на вход, но, опять же, я не могу понять это, когда кортеж ввода. Есть идеи?

+4

кортежи поддерживают индексирование. –

+0

Имея ссылку на звездный трек в заголовке вопроса, получает от меня верхнюю часть :) – krock

+1

@PadraicCunningham (с тех пор, как это делает 'a = (2, 0); print (a [0])' throw indexError? Поддержка индексирования индексов. .) Извините, забудьте, что я сказал, я неправильно прочитал ваш комментарий ... Извиняюсь! – Spirine

ответ

4

Действительно ли вам передается кортеж? Она смотрит на меня, что ваш конструктор должен быть просто:

def __init__(self, ft, inch=0): 
    self.ft = int(ft) 
    self.inch = int(inch) 

Это работает, если вы создаете объект с любой из них (потому что у вас есть значение по умолчанию для inch аргумента):

foo = Height(6) 
bar = Height(6, 3) 
baz = Height("5", 3) 

и т.д. Обратите внимание, что во втором и третьем экземплярах вам все равно не передается кортеж. Для того, чтобы действительно получить кортеж, вы должны были бы назвать его так:

foo2 = Height((6, 3)) 

или использовать «*» оператор в объявлении конструктора.

+0

Хотя это лучший способ обойти вещи, я должен указать, что объект высоты Тревора воспринимает 'ft' как дюймы, если есть только один аргумент. – cge

+0

Хорошая точка. На самом деле имеет смысл поддерживать ценность внутри одного устройства в любом случае (ножки или дюймы [или мм или что-то еще]), а затем преобразовывать его в привычные для человека ноги/дюймы на выходе, если это необходимо. –

1

Кортежи do поддержка индексирования. Они не поддерживают присвоение индексов, потому что они неизменяемы, но поддерживают индексный доступ.

Ваш код не работает, потому что ваш код предназначен для приема кортежа как ft. Он ничего не делает для int, что является совершенно другим аргументом. Все, что вам нужно сделать, это использовать вместо индексации:

class Height: 
    def __init__(self,ft,inch=0): 
     if isinstance(ft,tuple): 
      self.feet = ft[0] 
      self.inches = ft[1] 
     elif isinstance(ft,int): 
      self.feet = ft // 12 
      self.inches = ft % 12 
    def __str__(self): 
     return str(self.feet) + " Feet " + str(self.inches) + " Inches" 
    def __repr__(self): 
     return "Height (" + str(self.feet * 12 + self.inches) + ")" 

Однако, это работает только, если вы на самом деле проходят в кортеже, который ваш тестовый код никогда не делает! Height(5,6) просто проходит в двух аргументах. Для ввода кортежа вам понадобится Height((5,6)).

Как уже отмечалось, способ, которым вы его называете, на самом деле имеет больше смысла, чем использование кортежа. Для того, чтобы получить эту работу, вам просто нужно увидеть, если ваш второй аргумент используется (и давайте изменим к v1 и v2, по причинам, которые я получу позже):

def __init__(self, v1, v2=None): # set v2 to None, and then check to see if it isn't None 
    if v2 is not None: 
     self.feet = v1 
     self.inches = v2 
    else: 
     self.feet = v1 // 12 
     self.inches = v1 % 12 

Но есть проблема юзабилити: значение первого аргумента зависит от того, есть ли там второй аргумент! Вот почему называть его ft особенно плохо: если второй аргумент не предоставлен, он фактически находится в дюймах!

Одно решение это сделать оба аргументы имеют имена, что позволяет пользователю выбрать те, которые они хотят использовать:

def __init__(self, feet=0, inches=0): 
    self.feet = feet + inches // 12 
    self.inches = inches % 12 

Тогда у вас есть много вариантов, и меньше шансов путаницы:

In [4]: str(Height(5,0)) 
Out[4]: '5 Feet 0 Inches' 

In [5]: str(Height(0,5)) 
Out[5]: '0 Feet 5 Inches' 

In [6]: str(Height(5)) 
Out[6]: '5 Feet 0 Inches' 

In [7]: str(Height(inches=25)) 
Out[7]: '2 Feet 1 Inches' 

In [8]: str(Height(feet=3,inches=25)) 
Out[8]: '5 Feet 1 Inches' 
+0

Теперь должно быть яснее. – cge

1

У вас есть множество проблем в вашем коде, от форматирования до функциональности. Самое главное заключается в следующем:

elif isinstance(ft,int): 
    self.feet = ft // 12 
    self.inches = ft % 12 

так что если пользователь проходит ряд в ногах, предполагается, на самом деле быть в дюймах? Зачем?!


Я думаю, что вы в корне ошибаетесь, что происходит, когда вы звоните, например.

Height(5, 10) 

Внутри __init__, это эффективно устанавливает ft = 5 и inch = 10, неft = (5, 10).


Вот как я бы это сделал:

class Height: 

    def __init__(self, feet=0, inches=0): 
     self.feet, self.inches = feet, inches % 12 
     self.feet += inches // 12 

    def __str__(self): 
     return '{0.feet}\' {0.inches}"'.format(self) 

    def __repr__(self): 
     return 'Height({0.feet}, {0.inches})'.format(self) 

Это позволяет любому из следующих действий для правильной работы:

>>> Height() 
Height(0, 0) 
>>> Height(5, 0) 
Height(5, 0) 
>>> Height(5) 
Height(5, 0) 
>>> Height(inches=60) 
Height(5, 0) 
>>> print(str(Height(inches=123))) 
10' 3" 

Следует также отметить использование str.format и соблюдения the style guide. Другой альтернативой было бы повышение ошибки, если inches > 11 and feet > 0, поскольку это потенциально ошибочный ввод. Вы также можете посмотреть в emulating numeric types.

Смежные вопросы