3
\$\begingroup\$

I'm currently implementing data structures and algorithms I studed in my college course. This is my implementation of a singly linked list and a stack. I would appreciate some feedback in terms of the code quality.

My LinkedList:

from random import randint

class Node:

    def __init__(self, x):
        self.current = x
        self.next = None

class LinkedList:

    def __init__(self, x):
        self.head = Node(x)

    def insert(self, x):
        new_entry = Node(x)
        new_entry.next = self.head
        self.head = new_entry

    def search(self, x):
        node = self.head

        while node.current is not x:
            if node.next is None:
                break
            node = node.next

        if node.current is x:
            return x
        else:
            return None

    def contains(self, x):
        retrieved = self.search(x)
        return retrieved is x

    def delete(self, x):
        try:
            node = self.head

            while node.next.current is not x:
                node = node.next

            if node.next.current is x:
                node.next = node.next.next
        except AttributeError:
            print str(x) + " is not in the linked list"

    def traverse(self):
        node = self.head
        text = ""  # type: str

        while node is not None:
            text += str(node.current) + "->"
            node = node.next

        return text

My stack:

class Stack:

    def __init__(self):
        self.data = []

    def push(self, e):
        self.data.append(e)

    def pop(self):
        return self.data.pop()

    def prnt(self):
        print self.data

def is_integer(val):
    try:
        int(val)
        return True
    except ValueError:
        return False

def is_binary_operator(val):
    return val is '+' or val is '-' or val is '*' or val is '/'

def postfixEval(stack, expression):
    symbols = expression.split()

    for symbol in symbols:

        if is_integer(symbol):
            s = int(symbol)
            stack.push(s)
        elif is_binary_operator(symbol):
            s2 = stack.pop()
            s1 = stack.pop()

            if symbol is '+':
                a = s1 + s2
            elif symbol is '-':
                a = s1 - s2
            elif symbol is '*':
                a = s1 * s2
            elif symbol is '/':
                a = s1 / s2

            stack.push(a)

    return stack.pop()
\$\endgroup\$
1
  • 3
    \$\begingroup\$ This should be 2 separate questions, shouldn't it? \$\endgroup\$
    – Mast
    Commented May 19, 2018 at 21:27

2 Answers 2

2
\$\begingroup\$

Notes on LinkedList:

  • The import is unused.
  • It should allow creation of an empty list.
  • Normally a linked list inserts items after the last item. Maybe I'm confused by the way insert works, but it looks like in your case head is always the last inserted entry in the list, and the list is traversed from head backwards through history using .next.
  • delete should use search.

Notes on Stack:

  • self.data should be self.entries or something else descriptive.
  • prnt should be as_string or even __str__.
  • int(val) does not check whether something is an integer, it just tries to convert a value to an integer.
  • +, -, * and / are arithmetic, not binary, operators.
  • In Python 3 mathematical operators are modeled as functions.
  • is_integer, is_binary_operator and postfixEval should not be part of Stack - they are not fundamental to the stack in any way.
\$\endgroup\$
1
  • \$\begingroup\$ 'int(val) does not ...' No, but it does raise a ValueError if the argument can't be converted to an integer (which, when caught, results in the function returning False). \$\endgroup\$
    – Daniel
    Commented May 20, 2018 at 7:49
2
\$\begingroup\$
def is_integer(val):
    try:
        int(val)
        return True
    except ValueError:
        return False

Should be written:

def is_integer(val):
    try:
        int(val)            
    except ValueError:
        return False
    return True

This is cleaner because what may trigger the exception is not the return statement but when int() tries to convert val. Besides, maybe what you really are looking for is:

import numbers
def is_integer(val):
    return isinstance(val, numbers.Integral)

This way, you do not have to worry about exceptions since they are managed under the hood and, I think that is also the data type you want to deal with.

def prnt(self): print self.data

A stack has push(), pop() and size() operations, but nothing like prnt(). If you need the functionality prnt() is doing, take advantage of the Python __repr__() magic method instead:

 def __repr__(self):
     return '{} '.format(self.data)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.