Problem p03428 (python)

Fixed submission:
import math
pi=3.141592657589793238462643383279

#quoted from https://atcoder.jp/contests/agc021/submissions/2436528
def cross(C, A, B):
    return (C[0] - A[0])*(C[1] - B[1]) - (C[1] - A[1])*(C[0] - B[0])

def convex_hull(P):
    P.sort()
    Q = []
    for p in P:
        while 1 < len(Q) and cross(Q[-2], Q[-1], p) >= 0:
            Q.pop()
        Q.append(p)
    k = len(Q)
    for p in reversed(P[:-1]):
        while k < len(Q) and cross(Q[-2], Q[-1], p) >= 0:
            Q.pop()
        Q.append(p)
    return Q

n=int(input())
arr=[]
for _ in range(n):
  x,y=map(int,input().split())
  arr.append((x,y))
arr2=convex_hull(arr[:])[:-1]
ans=[0]*n
if n==2:
  print(0.5)
  print(0.5)
else:
  for i in range(n):
    pos=arr[i]
    if pos not in arr2:
      continue
    else:
      idx=arr2.index(pos)
      pos1=arr2[idx-1]
      pos2=arr2[(idx+1)%len(arr2)]
      x1=pos[0]-pos1[0]
      y1=pos[1]-pos1[1]
      x2=pos2[0]-pos[0]
      y2=pos2[1]-pos[1]
      angle=abs(math.atan2(x1*y2-x2*y1,x1*x2+y1*y2))
      ans[i]=angle/(2*pi)
  for i in range(n):
    print(ans[i])

Buggy submission (verdict: Runtime Error):
import math
pi=3.141592657589793238462643383279

#quoted from https://qiita.com/kkttm530/items/d6ca372491b75baeac3c
def signed_area(p1, p2, p3):
    '''符号付き面積を計算 '''

    area = (((p2[0] - p1[0]) * (p3[1] - p1[1])) - ((p3[0] - p1[0]) * (p2[1] - p1[1]))) / 2
    return area


def convex_hull(p_list):
    '''グラハムの凸包走査 '''

    p_sort = []
    for i in p_list:
        p_sort.append(i[0])

    # x座標が最小のものをリストの先頭に配置。
    min_index = p_sort.index(min(p_sort))
    min_p = p_list.pop(min_index)
    p_list.insert(0, min_p)

    # 座標最小の点と他の点との角度順にソート ソートアルゴリズムに選択の余地が有る。
    p_length = len(p_list)
    count = 0
    index = 0
    while True:
        count += 1
        index += 1

        area_sign = signed_area(p_list[0], p_list[index], p_list[index + 1])

        # 符号付き面積が負ならば点を入れ替え
        if area_sign < 0:
            p_list[index], p_list[index + 1] = p_list[index + 1], p_list[index]
            count = 0

        if count == p_length - 1:
            break

        if index == p_length - 2:
            index = 0

    # 凹部の点を削除する。
    index = -1
    count = 0
    while True:
        index += 1
        count += 1

        area_sign = signed_area(p_list[index], p_list[index + 1], p_list[index + 2])
        if area_sign < 0:
            del p_list[index + 1]
            count = 0

        if count == len(p_list):
            break

        if index >= len(p_list) - 3:
            index = -1
    return p_list

def getVectorLength(x,y):
  return (x**2+y**2)**0.5

def dotProduct(u,v):
  return u[0]*v[0]+u[1]*v[1]

def vectorsAngle(u,v):
  l1=getVectorLength(u[0],u[1])
  l2=getVectorLength(v[0],v[1])
  cosTheta=dotProduct(u,v)/(l1*l2)
  theta=math.acos(cosTheta)
  return 180*theta/pi
  
n=int(input())
arr=[]
for _ in range(n):
  x,y=map(int,input().split())
  arr.append((x,y))
arr2=convex_hull(arr[:])
ans=[0]*n
if n==2:
  print(0.5)
  print(0.5)
else:
  for i in range(n):
    pos=arr[i]
    if pos not in arr2:
      continue
    else:
      idx=arr2.index(pos)
      pos1=arr2[idx-1]
      pos2=arr2[(idx+1)%len(arr2)]
      x1=pos[0]-pos1[0]
      y1=pos[1]-pos1[1]
      x2=pos2[0]-pos[0]
      y2=pos2[1]-pos[1]
      angle=math.atan2(x1*y2-x2*y1,x1*x2+y1*y2)
      ans[i]=angle/(2*pi)
  for i in range(n):
    print(ans[i])