I finally figured out how to add body parts to my snake, but they add on in an unusual way. I have been struggling on this for a while, and finally made it so they append. But they don't do it correctly. It seems like they append 1 pixel behind instead of a full bodies length. Does anyone know why?
# Constants
WIN_WIDTH = 500
WIN_HEIGHT = 600
HALF_WIN_WIDTH = WIN_WIDTH / 2
HALF_WIN_HEIGHT = WIN_HEIGHT / 2
FPS = 10
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
DARK_GREEN = (0, 100, 0)
YELLOW = (255, 255, 0)
# Variables
screen = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
pygame.display.set_caption("Snake")
clock = pygame.time.Clock()
running = True
class Text:
    def __init__(self, x, y, size, font, color, text):
        self.x = x
        self.y = y
        self.size = size
        self.font = font
        self.color = color
        self.text = text
    def draw(self):
        self.my_font = pygame.font.SysFont(self.font, self.size)
        self.text_surface = self.my_font.render(self.text, True, self.color)
        screen.blit(self.text_surface, (self.x, self.y))
class Food:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 25
        self.height = 25
    def draw(self):
        self.rect = (self.x, self.y, self.width, self.height)
        pygame.draw.rect(screen, BLUE, self.rect)
    def events(self):
        pass
    def update(self):
        pass
class Body:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 25
        self.height = 25
    def draw(self):
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
        pygame.draw.rect(screen, YELLOW, self.rect)
# Snake class
class Snake:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 25
        self.height = 25
        self.direction = 1
        self.kill = False
        self.collide = False
        self.speed = 3
        self.score = 0
        self.bodies = []
    def draw(self):
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
        pygame.draw.rect(screen, BLACK, self.rect)
    def events(self):
        # change direction on key press
        self.keys = pygame.key.get_pressed()
        if self.keys[pygame.K_UP] and self.direction != 3:
            self.direction = 1
        if self.keys[pygame.K_DOWN] and self.direction != 1:
            self.direction = 3
        if self.keys[pygame.K_LEFT] and self.direction != 2:
            self.direction = 4
        if self.keys[pygame.K_RIGHT] and self.direction != 4:
            self.direction = 2
        if self.rect.colliderect(food.rect):
            self.speed += 0.5
            food.x = random.randint(0, WIN_WIDTH)
            food.y = random.randint(0, WIN_HEIGHT)
            self.score += 5
            self.colliide = False
            self.bodies.append(Body(0, 0))
        # Move the end bodies first in reverse order
        for i in range(len(self.bodies)-1, 0, -1):
            x = snake.bodies[i-1].x
            y = snake.bodies[i-1].y
            snake.bodies[i].x = x
            snake.bodies[i].y = y
            snake.bodies[i].draw()
        # Move body 0 to where the head is
        if len(snake.bodies) > 0:
            x = snake.x
            y = snake.y
            snake.bodies[0].x = x
            snake.bodies[0].y = y
            snake.bodies[0].draw()
    def update(self):
        # move
        if self.direction == 1:
            self.y -= self.speed
        if self.direction == 2:
            self.x += self.speed
        if self.direction == 3:
            self.y += self.speed
        if self.direction == 4:
            self.x -= self.speed
        # if on edge of screen
        if self.rect.right > WIN_WIDTH:
            self.kill = True
        if self.x < 0:
            self.kill = True
        if self.y < 0:
            self.kill = True
        if self.rect.bottom > WIN_HEIGHT:
            self.kill = True
# Create the snake object
snake = Snake(HALF_WIN_WIDTH, HALF_WIN_HEIGHT)
food = Food(random.randint(0, WIN_WIDTH), random.randint(0, WIN_HEIGHT))
# Main Loop
while running:
    score_text = Text(220, 5, 40, 'arial', WHITE, f'Score: {snake.score}')
    # Draw
    screen.fill(DARK_GREEN)
    snake.draw()
    food.draw()
    score_text.draw()
    # Event handling
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    if snake.kill:
        running = False
    snake.events()
    # Update
    snake.update()
    food.update()
    clock.tick(60)
    pygame.display.update()
Thank you very much!
