Как бы я обойти этот недопустимый литерал для int () с ошибкой базы 10? - PullRequest
0 голосов
/ 09 ноября 2019
import math

# The standard gravitational parameter for the sun
mu = 1.327 * math.pow(10, 20)

class Planet:
  def __init__(self, name, radius, moons, orbital_radius):
    self.name = name
    self.radius = radius
    self.moons = moons
    self.orbital_radius = orbital_radius

  def collide(self):
    self.moons = self.moons + 1
    return self.moons


def volume(Planet):
  v = (4 / 3) * math.pi * math.pow(Planet.radius, 3)
  return str(v)

def surface(Planet):
  area = 4 * math.pi * math.pow(Planet.radius, 2)
  return str(area)  

def physical(Planet):
  if Planet.moons == 1:
    Planet.moons = str(Planet.moons) + " moon"
  else:
    Planet.moons = str(Planet.moons) + " moons"
  return (Planet.name + " has a volume of " + volume(Planet) + " cubic km, a surface area of " + surface(Planet) + " sq. km, and " + Planet.moons)

def dynamic(Planet):
  period = 2 * math.pi * Planet.orbital_radius * math.sqrt(Planet.orbital_radius / mu)
  return (Planet.name + " has a year of approximately " + str(period // (60 * 60 * 24)) + " days")

Earth = Planet('Earth', 6371, 1, 1.496 * math.pow(10, 11))
Jupiter = Planet('Jupiter', 69911, 79, 7.786 * math.pow(10, 11))

print(physical(Earth))
print(physical(Jupiter))
print(dynamic(Earth))
print(dynamic(Jupiter))

print(Earth.collide())

Я понимаю, что self.moons превращается в строку из-за физической функции, но как бы я снова превратился в целое число? Это не представляется возможным, поскольку целое число и строка сохраняются в качестве значения, поэтому я получаю сообщение об ошибке ValueError: invalid literal for int() with base 10: '1 moon' при попытке print(Earth.collide())

Ответы [ 2 ]

1 голос
/ 09 ноября 2019

Просто разбейте строку на пробел и возьмите первую часть:

int(self.moon.partition(" ")[0])

Вы также можете использовать str.split(), но разбиение происходит немного быстрее для случая «нужно только один раз».

Подход лучше состоит в том, чтобы не устанавливать атрибут .moons в строку. Держите его целым числом, нет необходимости заменять его, просто отформатировав красивую строку с информацией:

def physical(Planet):
    if Planet.moons == 1:
        moons = str(Planet.moons) + " moon"
    else:
        moons = str(Planet.moons) + " moons"
    return (Planet.name + " has a volume of " + volume(Planet) + " cubic km, a surface area of " + surface(Planet) + " sq. km, and " + moons)

Вы можете посмотреть отформатированные строковые литералы или синтаксис строки формата :

def physical(Planet):
    moons = f"{Planet.moons} moon"
    if Planet.moons != 1:
        moons += 's'
    return (
        f"{Planet.name} has a volume of {volume(Planet)} cubic km, a surface "
        f"area of {surface(Planet)} sq. km, and {moons}"
    )

В любом случае, используя локальную переменную moons для хранения отформатированного значения количество лун , вы не изменяете Planet.moons значение, так что не нужно беспокоиться о том, чтобы вернуться к нему, являющемуся целым числом снова.

0 голосов
/ 09 ноября 2019

Я бы порекомендовал придерживаться локальной / приватной переменной в def physical(Planet), потому что она больше нигде не используется, а просто форматирует значение.

def physical(Planet):
  if Planet.moons == 1:
    _planet_moons = str(Planet.moons) + " moon"
  else:
    _planet_moons = str(Planet.moons) + " moons"
  return (Planet.name + " has a volume of " + volume(Planet) + " cubic km, a surface area of " + surface(Planet) + " sq. km, and " + _planet_moons)

Это предотвращает преобразованиезначение вперед и назад.

...