The error occurs because you have head.next = newval where newval is a number, but you should be assigning a node instance, i.e. newnode. So the next time you iterate the list, like in print_list you'll bump into that integer, and access its data attribute, as if it is a node...
Some other remarks on your code:
- Your - linkedlistclass has no state. It merely provides some functions that act on the- headargument. The OOP way to do this, is to give a- linkedlistinstance its own- headattribute. And then rely on the- selfargument, which in your current code is not used in the functions.
 
- Your main code should not have to deal with - nodeinstances. It should just have to create a- linkedlist, and then populate it by calling its method(s). For that to work you'll have to deal with the case where the list is empty, and a first value is added to it, because then its- headattribute needs to be set to it.
 
- Use PascalCase for naming your classes. 
- The name of the - print_listfunction is misleading: it doesn't print, but returns a list. So I would name it- to_listinstead.
 
- Don't print the result of calling - vals.add_at_end, because it is not designed to return anything, so you'll be printing- None.
 
Corrected:
class Node():  # Use PascalCase
    def __init__(self, data):
        self.data = data
        self.next = None
class LinkedList():
    def __init__(self):
        self.head = None  # Give each instance its own head attribute
    def add_at_end(self, newval):
        if not self.head:  # Deal with this case
            self.head = Node(newval)
        else:
            head = self.head  # Use attribute
            while head.next:
                head = head.next
            head.next = Node(newval)  # corrected  
    def to_list(self):  # Better name
        LL = []
        head = self.head  # Use attribute
        while head:
            LL.append(head.data)
            head = head.next
        return LL
vals = LinkedList()
vals.add_at_end(5)  # Use method to add nodes
vals.add_at_end(6)
vals.add_at_end(2)
vals.add_at_end(8)  # Nothing to print here
print(vals.to_list())