Spencer Gibson
Spencer Gibson

Reputation: 1

Calculating Sun Angle Code

My goal with this code was to write a code that measures the degree measure of the sun having that at 6:00 the angle is 0 and at 18:00 the angle is 180 degrees. I tried to make the time input a string and then loop through its characters and pick out the integers and put it into the list that way I could avoid the colon. It seems that this is still a problem. Can someone explain to me what's wrong with this code? Why do I keep getting an "unsupported operand type error"?

def sun_angle(time):

    lis = []
    time = str(time)
    for i in time:
        if i.isdigit():
            lis.append(i)
        else: 
            continue
    a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
    b = a - 6
    if b < 6 or b > 18:
        return "I can't see the sun!"
    else:
        return b * 15
print(sun_angle("12:12"))

Upvotes: 0

Views: 1029

Answers (4)

dominic parker
dominic parker

Reputation: 13

You need to cast lis[i] to integer when you're calculating the value of a. 07:00 means sun is up, your logic fails and 18:01 means sun is down.

def sun_angle(time_):
    lis = []
    time_ = str(time_)
    for i in time_:
        if i.isdigit():
            lis.append(i)
        else: 
            continue
    a = int(lis[0])*10 
    a += int(lis[1]) 
    bb = (int(lis[2])*10 + int(lis[3]))
    #print a
    #print bb
    #b = a - 6
    if (a < 6 or a > 18) or (a == 18  and bb > 0):
        return "I can't see the sun!"
    else:
        return (float(a)-6.0) * 15.0 + (15.0*float(bb))/60.0

Upvotes: 0

j4rey
j4rey

Reputation: 2677

Your error line is:

a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))

since time is a string type

def sun_angle(time):

    lis = []
    time = str(time)
    for i in time:
        if i.isdigit():
            lis.append(int(i)) #cast it to type int
        else: 
            continue
    a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
    b = a - 6
    if b < 0 or b >= 12:
        return "I can't see the sun!"
    else:
        return b * 15
print(sun_angle("12:12"))

output: 90

Upvotes: 0

Michael Swartz
Michael Swartz

Reputation: 858

If you change the above similar line to:

a = int(lis[0]) * 10 + int(lis[1]) + ((int(lis[2]) + int(lis[3]))/60)

then you get a result. The problem on that line is that you're mixing int and str types. And since you're already passing in a string you can change time = str(time) to time = time. Casting time to a string is redundant.

Upvotes: 0

Nick White
Nick White

Reputation: 2061

Michael's answer is a great explanation for why what you're doing isn't working (need to convert string to int before manipulating with * and +).

However, there are a lot of ways to parse the time that will be easier to work with than what you're doing here. I'd consider splitting and then parsing the two parts, or you could use the datetime library for more complexity:

# option 1
def parse_time_as_hour(time_str):
  hour_str, min_str = time_str.split(':')
  return int(hour_str) + int(min_str) / 60.0

# option 2
import datetime
def parse_time_as_hour(time_str):
  parsed = datetime.datetime.strptime(time_str, '%H:%M')
  return parsed.hour + parsed.minute / 60.0

def sun_angle(time):
  fractional_hour = parse_time_as_hour(time)
  if fractional_hour < 6 or fractional_hour >= 18:
    return "I can't see the sun!"
  else:
    return (fractional_hour - 6) * 15

Upvotes: 1

Related Questions