chas108
chas108

Reputation: 29

How do i print actual data and not memory locations of an object?

Im trying to make a linked list in python and would like to print out the things but its printing as a memory location. We learnt how to fix this in class but im on half term at the moment and have nobody to ask.

An example of what im currently getting:

List: <__main__.LinkedList object at 0x02EA0100>
 index: 0    data: 1     item: <__main__.Node object at 0x02EA00D0>  pointer: <__main__.Node object at 0x02EA0148>
 index: 1    data: 6     item: <__main__.Node object at 0x02EA0148>  pointer: <__main__.Node object at 0x02EA0190>
 index: 2    data: 3     item: <__main__.Node object at 0x02EA0190>  pointer: None

This is not very usefull to me.

The method im using to get this masterpice:

def PrintList(self):
    item = self.list_start
    index = 0
    print(f"List: {self}")
    while item:
        print(
            f"\t index: {index}\t data: {item.data}\t item: {item}\t pointer: {item._get_pointer()}"
            )
        item = item._get_pointer()
        index += 1

Im sure theres something wrong in the print line i just cant spot it.

I know your not supposed to put loads of code on here but i need to give context

Node Class:

class Node:
def __init__(self, data=None, pointer=None):
    self.data = data
    self.poiner = pointer

def PrintNode(self):
    print(f"Node Data: {self.data}\t self: {self}\t pointer: {self.pointer}\n")

def _set_pointer(self, pointer):
    self.pointer = pointer

def _get_pointer(self):
    return self.pointer

LinkedLis Class:

class LinkedList:
def __init__(self):
    self.list_start = None

def PrintList(self):
    item = self.list_start
    index = 0
    print(f"List: {self}")
    while item:
        print(
            f"\t index: {index}\t data: {item.data}\t item: {item}\t pointer: {item._get_pointer()}"
            )
        item = item._get_pointer()
        index += 1

def _isleagl(self, node):
    if node is None:
        print(f"node' is None")
        return False
    elif type(node) != Node:
        print(f"'node' has worng type: {type(node)}")
        return False
    else:
        return True

def AppendNode(self, node):
    if self._isleagl(node):
        if self.list_start == None:
            self.list_start = node
            node._set_pointer(None)
        else:
            item = self.list_start
            while item:
                if item == node:
                    node = copy.deepcopy(node)
                elif item._get_pointer() is None:
                    item._set_pointer(node)

                    node._set_pointer(None)
                    break
                else:
                    item = item._get_pointer()

def DeleteNode(self, node):
    if self._islegal(node):
        if self.list_start == node:
            self.list_start = node._get_pointer()
        else:
            item = self.list_start
            while item:
                if item._get_pointer() == node:
                    item._set_pointer(node._get_pointer())
                break
            item = item._get_pointer()

Menu system: #i dont think this is going to be of much help

def main():
my_list = None
my_node = None
while True:
    print("Node Manipulations")
    print("\t 0: Create Node")
    print("\t 1: Set Node Data")
    print("\t 2: Print Node")
    print()
    print("List Manipulations")
    print("\t 3: Create List")
    print("\t 4: Print List")
    print("\t 5: Append Node to List")
    print("\t 6: Delete Node from List")
    print()
    print("X: EXIT Program")
    choice = input("->")
    if choice not in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "X", "x"]:
        continue

    if choice == "X" or choice == "x":
         break

    elif choice == "0":
        my_node = Node()

    elif choice == "1":
        if my_node is None:
            print("Create Node first")
        else:
            my_node.data = input("Node Data? -> ")

    elif choice == "2":
        if my_node is None:
           print("Create Node first")
        else:
            my_node.PrintNode()

    elif choice == "3":
        my_list = LinkedList()

    elif choice == "4":
        if my_list is None:
           print("Create List first")
        else:
            my_list.PrintList()
            print()

    elif choice == "5":
        if my_list is None:
            print("Create List first")
        else:
            my_list.AppendNode(my_node)

    elif choice == "6":
        if my_list is None:
            print("Create List first")
        else:
            my_list.DeleteNode(my_node)

Upvotes: 0

Views: 1527

Answers (2)

Karan Gehlod
Karan Gehlod

Reputation: 357

"<main.K object at 0x01481FE8>" try xyz=str(x.data) print(xyz) xyz will give you data stored at that location. use it in loop if you are using an list or any data structure. faced similar problem in a program it helped.

Upvotes: 0

Toothpick Anemone
Toothpick Anemone

Reputation: 4644

Try running the following code:

class K:
    pass

obj = K()
print(obj)

The output is:

<__main__.K object at 0x01481FE8>

By default, if you don't write a "to string" method (or __str__()) the garbage above is what python will produce as a string. Note that the function print can only print strings. It cannot print integers, or anything else. As such print(n) will convert all inputs to strings before printing them. The code below describes what the built-in print function does:

import sys
def print(*args, sep=" ", end"\n", file=sys.stdout):
    file.write(sep.join(map(str, args)) + end) 

So, write your own __str__ method:

import sys
import io
class Node:
    def __init__(self, data=None, pointer=None):
        self.data = data
        self.pointer = pointer

    def print_node(self, *, sep="\t", file=sys.stdout):
        print(
            f"Node Data: {self.data}",
            f"self: {id(self)}",
            f"pointer: {id(self.pointer)}",
            sep=sep,
            file=file
        )

    def _set_pointer(self, pointer):
        self.pointer = pointer

    def _get_pointer(self):
        return self.pointer

    def __str__(self):
        with io.StringIO() as string_stream:
            self.print_node(file=string_stream)
            stryng = string_stream.getvalue()
        return stryng

Your print node method was originally named PrintNode. Never begin something with a capital letter unless it is a class. Either write printNode or print_node.

Secondly, I changed f"pointer: {self.pointer}" to f"pointer: {id(self.pointer)}"

Suppose that you did not do that. Well then, print_node would print self.pointer. But self.pointer is a node, so it would then print self.pointer.pointer. But self.pointer.pointer is a node, so then it would print self.pointer.pointer.pointer, and so on... You don't want that. The memory address of an object can be retrieved with the id() function.

Also, it's a bad idea for print_node to print self. That's just begging for an infinite recursion. How do I print self? well, I print data, self, and pointer. That means I gotta print self, which means I gotta print self, which means I gotta print self, and so on, forever, and ever.

Upvotes: 1

Related Questions