i was following this tutorial on decision trees and I tried to recreate it on my own as python project, instead of a notebook, using spyder.
I create different py files where I put different methods and classes, specifically I create a file named tree_structure with the following classes: Leaf, DecisionNode and Question. (I hope it's correct to put more classes in a single py file)
When I tried to use isinstance() in method "classify" in another py file, I was expecting True instead it returned False:
>>>leaf0
<tree_structure.Leaf at 0x11b7c3450>
>>>leaf0.__class__
tree_structure.Leaf
>>>isinstance(leaf0,Leaf)
False
>>>isinstance(leaf0,tree_structure.Leaf)
False
leaf0 was created iteratively from "build_tree" method (I just saved it to t0 for debugging.. during execution is not saved as a variable) :
t0 = build_tree(train_data)
leaf0 = t0.false_branch.false_branch
I tried also using type(leaf0) is Leaf instead of isinstance but it still returns False.
Can someone explain me why this happen?
tree_structure.py
class Question:
def __init__(self,header, column, value):
self.column = column
self.value = value
self.header = header
def match(self, example):
# Compare the feature value in an example to the
# feature value in this question.
val = example[self.column]
if is_numeric(val):
return val >= self.value
else:
return val == self.value
def __repr__(self):
# This is just a helper method to print
# the question in a readable format.
condition = "=="
if is_numeric(self.value):
condition = ">="
return "Is %s %s %s?" % (
self.header[self.column], condition, str(self.value))
class Leaf:
def __init__(self, rows):
self.predictions = class_counts(rows)
class DecisionNode:
def __init__(self,
question,
true_branch,
false_branch):
self.question = question
self.true_branch = true_branch
self.false_branch = false_branch
classifier.py
from tree_structure import Question,Leaf,DecisionNode
def classify(row, node):
# Base case: we've reached a leaf
if isinstance(node, Leaf):
print("----")
return node.predictions
# Decide whether to follow the true-branch or the false-branch.
# Compare the feature / value stored in the node,
# to the example we're considering.
if node.question.match(row):
print("yes")
return classify(row, node.true_branch)
else:
print("no")
return classify(row, node.false_branch)
build_tree
def build_tree(rows,header):
"""Builds the tree.
Rules of recursion: 1) Believe that it works. 2) Start by checking
for the base case (no further information gain). 3) Prepare for
giant stack traces.
"""
gain, question = find_best_split(rows,header)
print("--best question is ''{}'' with information gain: {}".format(question,round(gain,2)))
# Base case: no further info gain
# Since we can ask no further questions,
# we'll return a leaf.
if isinstance(rows,pd.DataFrame):
rows = rows.values.tolist()
if gain == 0:
return Leaf(rows)
# If we reach here, we have found a useful feature / value
# to partition on.
true_rows, false_rows = partition(rows, question)
# Recursively build the true branch.
print("\n----TRUE BRANCH----")
true_branch = build_tree(true_rows,header)
# Recursively build the false branch.
print("\n----FALSE BRANCH----")
false_branch = build_tree(false_rows,header)
# Return a Question node.
# This records the best feature / value to ask at this point,
# as well as the branches to follow
# dependingo on the answer.
return DecisionNode(question, true_branch, false_branch)
Related
Long story short, I need to write a data analysing tool using mainly OOP principles. I'm not quite a beginner at python but still not the best. I wrote a function which returned true or false value based on what the user inputted (below):
def secondary_selection():
"""This prints the options the user has to manipulate the data"""
print("---------------------------")
print("Column Statistics [C]")
print("Graph Plotting [G]")
d = input(str("Please select how you want the data to be processed:")).lower()
# Returns as a true/false boolean as it's easier
if d == "c":
return True
elif d == "g":
return False
else:
print("Please enter a valid input")
This function works the way I want it to, but I then tried to import it into different file for use with a class (below):
class Newcastle:
def __init__(self, data, key_typed):
self.data = data[0]
self.key_typed = key_typed
def newcastle_selection(self):
# If function returns True
if self:
column_manipulation()
# If function returns False
if not self:
graph_plotting()
The newcastle_selection(self) function takes the secondary_selection() function as a argument, but the only way I got it to work was the if self statement. As writing something like if true lead to both the column_manipulation and the graph_plotting functions being printed.
I am wondering if there's any better way to write this as I am not quite a beginner at python but still relatively new to it.
Disclaimer: This is for a first year course, and I asked this as a last result.
I'm not sure I've understood really well your code structure, but it looks like a little factory could helps you:
def column_manipulation():
print("Column manipulation")
def graph_plotting():
print("Graph plotting")
class Newcastle:
def __init__(self, data, func):
self.data = data[0]
self._func = func
def newcastle_selection(self):
return self._func()
#classmethod
def factorize(cls, data, key_typed):
if key_typed is True:
return cls(data, column_manipulation)
elif key_typed is False:
return cls(data, graph_plotting)
else:
raise TypeError('Newcastle.factorize expects bool, {} given'.format(
type(key_typed).__name__
))
nc = Newcastle.factorize(["foo"], True)
nc.newcastle_selection()
nc = Newcastle.factorize(["foo"], False)
nc.newcastle_selection()
Output
Column manipulation
Graph plotting
The main idea is to define your class in a generic way, so you store a function given as __init__ parameter within self._func and just call it in newcastle_selection.
Then, you create a classmethod that takes your data & key_typed. This method is in charge of choosing which function (column_manipulation or graph_plotting) will be used for the current instance.
So you don't store useless values like key_typed in your class and don't have to handle specific cases everywhere, only in factorize.
Cleaner and powerful I think (and btw it answer your question "Is this pythonic", this is).
This is simple and basic example of secondary_selection method using class. This would help probably.
class castle:
def __init__(self):
self.data = ''
def get_input(self):
print("1: Column Statistics")
print("2: Graph Plotting")
self.data = input("Please select how you want the data to be processed: ")
def process(self):
if self.data == 1:
return self.column_manipulation()
else:
return self.graph_plotting()
def column_manipulation(self):
return True
def graph_plotting(self):
return False
c = castle()
c.get_input()
result = c.process()
print(result)
I have just implemented my first Binary Tree:
class BinaryTree:
def __init__(self, obj):
self.key = obj
self.left_c = None
self.right_c = None
def insert_left_c(self, new_node):
if self.left_c == None:
self.left_c = BinaryTree(new_node)
else:
temp = BinaryTree(new_code)
temp.left_c = self.left_c
self.left_c = temp
def insert_right_c(self, new_node):
if self.right_c == None:
self.right_c = BinaryTree(new_node)
else:
temp = BinaryTree(new_code)
temp.right_c = self.right_c
self.right_c = temp
def set_root(self, obj):
self.key = obj
def get_root(self):
return self.key
def get_left_c(self):
return self.left_c
def get_right_c(self):
return self.right_c
I am struggling to understand how you actually go about building a tree to ones specifications. As an example, I am trying to build the following tree:
However, I am really struggling to understand / visualize how you build the lower nodes and manipulate their left / right branches.
I though I may be able to do something such as:
binary_tree = BinaryTree('a')
binary_tree.insert_left_c('b')
binary_tree.insert_right_c('d')
binary_tree.insert_right_c('c')
binary_tree.insert_left_c('e')
binary_tree.insert_right_c('f')
But I realize that is nonsensical because I believe I'm creating a unique node for all letters that would be on the same level? I never actually set one to be a child of another(?).
If someone could explain how one should go about solving this, and visualizing similar problems, I would much appreciate it.
Your insert functions only operate on the root, without traversing deeper into the tree. Usually, such a function would insert into a binary search tree, recursing left or right depending on how the value to insert compares to the root of the current tree. For a general binary tree, you would want to pass an explicit list of left/right directions to specify where a new value goes.
It would be simpler to just build the tree explicitly. Start with individual trees for each leaf, then merge them.
trees = {x: BinaryTree(x) for x in 'abcdef'}
binary_tree = trees['a']
binary_tree.left_c = trees['b']
binary_tree.right_c = trees['c']
trees['b'].right_c = trees['d']
trees['c'].left_c = trees['e']
trees['c'].right_c = trees['f']
I've been trying to create a simple linked list implementation in Python as a code exercise and, although I have most of the stuff working (inserting, removing, pretty print, swapping the content of two nodes), I've been stuck on swapping two nodes for a few days.
I've looked around on the internet and most people seem to recommend deleting/inserting the nodes or swapping the data. Both are very fine and functional options but I wanted to challenge myself and see if I could swap the nodes the "correct" way.
Ideally I would like to have a generic function that can handle all edge cases (moving to the begin, end and swapping random nodes). This has proven to be way more challenging than I expected.
I've experimented a bit with pen and paper and search around and I found the following discussion and example implementation:
Discussion about swapping in C
Example implementation in C
The issue I run into is that my node1.next and my node2.prev are swapped and that my node2.next refers to itself and not to the next node in the list.
The comment on the page of the example implementation specifically addresses this problem and mentions that it should not happen with his implementation.
I can't seem to figure out what I've done wrong. I guess I could "cheat" and force them to take the correct values at the end but that gives a lot of problems when the node is the first/last.
__author__ = 'laurens'
from django.core.exceptions import ObjectDoesNotExist
import logging
import copy
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
class DoublyLinkedList(object):
"""This class implements a basic doubly linked list in Django, it depends
on a Django model with the following field:
id : PK
prev: integer previous node
data_field: Foreign key
next: integer next node
the prev and next fields don't need to be self-referencing
When instantiating the class you have to link this class to a Django model
and specify a data field. The data field can link to a foreign key
or contain data
"""
def __init__(self, doubly_linked_list_model, data_field):
self.doubly_linked_list_model = doubly_linked_list_model
self.data_field = data_field
def get_node_from_node_id(self, node_id=None):
"""This function returns the node associated with a certain node_id"""
if node_id is None:
node = None
else:
try:
node = self.doubly_linked_list_model.get(id=node_id)
except ObjectDoesNotExist:
node = None
return node
#staticmethod
def _update_node(node, prev=None, next=None):
node.prev = prev
node.next = next
logger.debug('updating node: %s', node.id)
logger.debug('node.prev = %s', node.prev)
logger.debug('node.next = %s', node.next)
try:
node.save()
except Exception as e: #Todo: specify this
logger.debug('Error saving node: %s', node.id)
def move_node(self, node1=None, node2=None):
"""
This function swaps the position of node1 with the position of node2
"""
#swapping two nodes!
logger.debug('Swapping two random nodes!: %s, %s', node1.id, node2.id)
# Swapping next nodes
logger.debug('Swapping next node')
tmp = copy.deepcopy(node1.next)
self._update_node(node=node1,
prev=node1.prev,
next=node2.next)
#Todo: Check if tmp changes or is stored as a copy
self._update_node(node=node2,
prev=node2.prev,
next=tmp)
if node1.next is not None:
logger.debug('Connect the next node to node 1')
node_next = self.get_node_from_node_id(node1.next)
self._update_node(node=node_next,
prev=node1.id,
next=node_next.next)
if node2.next is not None:
logger.debug('Connect the next node to node 2')
node_next = self.get_node_from_node_id(node2.next)
self._update_node(node=node_next,
prev=node2.id,
next=node_next.next)
logger.debug('Swap prev nodes')
tmp = copy.deepcopy(node1.prev)
self._update_node(node=node1,
prev=node2.prev,
next=node1.next)
self._update_node(node=node2,
prev=tmp,
next=node2.next)
# Connect the node before node1 to node 1
if node1.prev is not None:
logger.debug('Connect the prev to node 1')
node_prev = self.get_node_from_node_id(node1.prev)
self._update_node(node=node_prev,
prev=node_prev.prev,
next=node1.id)
# Connect the node before node2 to node 2
if node2.prev is not None:
logger.debug('Connect the prev to node 2')
node_prev = self.get_node_from_node_id(node2.prev)
self._update_node(node=node_prev,
prev=node_prev.prev,
next=node2.id)
The _update_node function does nothing more than taking my input and committing it to the database; it can handle None values.
get_node_from_node_id takes an integer as input and returns the node object associated with it. I use it so that I don't have to work with self-referencing foreign keys (is that the correct term?) in the database, for now I would like to continue working this way. Once I have this working I'll move on to fixing it in the database in the correct way.
tip: I get answers much more quickly when I provide a minimal, complete, verifiable example (MCVE), also known as a short, self-contained, compilable example (SSCCE).
Your example code fails to demonstrate the problem, making it impossible for us to help you.
Please make it easy for us to help you.
I ran your example code, but I didn't see any output.
The issue I run into is that ... that my node2.next refers to itself and
not to the next node in the list.
Why is node2.next referring to node2 a problem?
As far as I can tell, the part of the code you gave us so far works fine.
Some of the most difficult debugging sessions I've ever had ended only when I realized that everything was actually working correctly, that the "bug" I thought I was hunting didn't actually exist.
Yes, there is an intermediate step halfway through the algorithm where a node refers to itself, which may seem obviously wrong.
But then the second half of the algorithm makes further changes.
By the time the algorithm finishes,
the "next" chain correctly runs all the way from the beginning to the end, and
the "forward" chain correctly runs in the reverse order as the "next" chain, from the end to the beginning, and
the order of those chains is similar to the original order, except that node1 and node2 have swapped logical position (but are still in the same physical position).
Every node points to 2 other nodes (or to the NULL node), never to itself.
Isn't that what you wanted?
When I ran the following test script, I get lots of output --
but I don't see any problems in the output.
(I used a simple array with integer indexes rather than true pointers or references to make the code shorter and easier to debug compared to a SQL database).
Would you mind pointing out which particular line of output is not what you expected, and spelling out what you expected that line of output to actually say?
#!/usr/bin/env python
# https://stackoverflow.com/questions/24610889/trying-to-write-a-swap-position-function-for-a-doubly-linked-list
# Is this the shortest possible program that exhibits the bug?
# Before running this probram, you may need to install
# sudo apt-get install python-django
# 2015-03-12: David added some test scaffolding
# 2014-07-07: Laurens posted to StackOverflow
__author__ = 'laurens'
from django.core.exceptions import ObjectDoesNotExist
import logging
import copy
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
class DoublyLinkedList(object):
"""This class implements a basic doubly linked list in Django, it depends
on a Django model with the following field:
id : PK
prev: integer previous node
data_field: Foreign key
next: integer next node
the prev and next fields don't need to be self-referencing
When instantiating the class you have to link this class to a Django model
and specify a data field. The data field can link to a foreign key
or contain data
"""
def __init__(self, doubly_linked_list_model, data_field):
self.doubly_linked_list_model = doubly_linked_list_model
self.data_field = data_field
def get_node_from_node_id(self, node_id=None):
"""This function returns the node associated with a certain node_id"""
if node_id is None:
node = None
else:
try:
node = self.doubly_linked_list_model.get(id=node_id)
except ObjectDoesNotExist:
node = None
return node
#staticmethod
def _update_node(node, prev=None, next=None):
node.prev = prev
node.next = next
logger.debug('updating node: %s', node.id)
logger.debug('node.prev = %s', node.prev)
logger.debug('node.next = %s', node.next)
try:
node.save()
except Exception as e: #Todo: specify this
logger.debug('Error saving node: %s', node.id)
def move_node(self, node1=None, node2=None):
"""
This function swaps the position of node1 with the position of node2
"""
#swapping two nodes!
logger.debug('Swapping two random nodes!: %s, %s', node1.id, node2.id)
# Swapping next nodes
logger.debug('Swapping next node')
tmp = copy.deepcopy(node1.next)
self._update_node(node=node1,
prev=node1.prev,
next=node2.next)
#Todo: Check if tmp changes or is stored as a copy
self._update_node(node=node2,
prev=node2.prev,
next=tmp)
if node1.next is not None:
logger.debug('Connect the next node to node 1')
node_next = self.get_node_from_node_id(node1.next)
self._update_node(node=node_next,
prev=node1.id,
next=node_next.next)
if node2.next is not None:
logger.debug('Connect the next node to node 2')
node_next = self.get_node_from_node_id(node2.next)
self._update_node(node=node_next,
prev=node2.id,
next=node_next.next)
logger.debug('Swap prev nodes')
tmp = copy.deepcopy(node1.prev)
self._update_node(node=node1,
prev=node2.prev,
next=node1.next)
self._update_node(node=node2,
prev=tmp,
next=node2.next)
# Connect the node before node1 to node 1
if node1.prev is not None:
logger.debug('Connect the prev to node 1')
node_prev = self.get_node_from_node_id(node1.prev)
self._update_node(node=node_prev,
prev=node_prev.prev,
next=node1.id)
# Connect the node before node2 to node 2
if node2.prev is not None:
logger.debug('Connect the prev to node 2')
node_prev = self.get_node_from_node_id(node2.prev)
self._update_node(node=node_prev,
prev=node_prev.prev,
next=node2.id)
global_test_array = []
obfuscation = 0xaa
class trivial_test_node_class(object):
def __init__(self, prev, id, next, data):
print "initializing test class."
# self.stuff = [ ["first", 0, 1], ["second", 0, 1] ]
self.id = id
self.prev = prev
self.next = next
self.data = data
def something(self):
print "something"
def save(self):
id = self.id
global_test_array[id] = self
def __repr__(self):
# print self.prev, self.id, self.next, self.data
the_string = "%s(%r)\n" % (self.__class__, self.__dict__)
return the_string
class trivial_test_list_model_class(object):
def __init__(self):
print "initializing test class."
#self.stuff = [ ["first", 0, 1], ["second", 0, 1] ]
self.stuff = [ 0 for i in xrange(0,10) ]
data = 'a'
for i in xrange(1,10):
self.stuff[i] = trivial_test_node_class(i-1,i,i+1,data);
data += 'r' # talk like a pirate day
self.stuff[-1].next = 0 # use 0 as NULL id.
global global_test_array
global_test_array = self.stuff
def something(self):
print "something"
def get(self,id):
return self.stuff[id]
def __repr__(self):
# for i in xrange(1,10):
# print self.stuff[i]
the_string = "%s(%r)" % (self.__class__, self.__dict__)
return the_string
if __name__ == '__main__':
# test code that only gets run when this file is run directly,
# not when this file is imported from some other python script.
print "Hello, world."
trivial_test_model = trivial_test_list_model_class()
print trivial_test_model
testll = DoublyLinkedList( trivial_test_model, "data" )
left_node = trivial_test_model.get(3)
right_node = trivial_test_model.get(4)
testll.move_node( left_node, right_node )
print trivial_test_model
# recommended by http://wiki.python.org/moin/vim
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 :
I have been subclassing an Python's random number generator to make a generator that doesn't repeat results (it's going to be used to generate unique id's for a simulator) and I was just testing to see if it was consistent in it's behavior after it has been loaded from a previours state
Before people ask:
It's a singleton class
No there's nothing else that should be using that instance (a tear down sees to that)
Yes I tested it without the singleton instance to check
and yes when I create this subclass I do call a new instance ( super(nrRand,self).__init__())
And yes according to another post I should get consistent results see: Rolling back the random number generator in python?
Below is my test code:
def test_stateSavingConsitantcy(self):
start = int(self.r.random())
for i in xrange(start):
self.r.random()
state = self.r.getstate()
next = self.r.random()
self.r.setstate(state)
nnext = self.r.random()
self.assertEqual(next, nnext, "Number generation not constant got {0} expecting {1}".format(nnext,next))
Any help that can be provided would greatly appreciated
EDIT:
Here is my subclass as requested
class Singleton(type):
_instances = {}
def __call__(self, *args, **kwargs):
if self not in self._instances:
self._instances[self] = super(Singleton,self).__call__(*args,**kwargs)
return self._instances[self]
class nrRand(Random):
__metaclass__ = Singleton
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
super(nrRand,self).__init__()
self.previous = []
def random(self):
n = super(nrRand,self).random()
while n in self.previous:
n = super(nrRand,self).random()
self.previous.append(n)
return n
def seed(self,x):
if x is None:
x = long(time.time()*1000)
self.previous = []
count = x
nSeed = 0
while count < 0:
nSeed = super(nrRand,self).random()
count -= 1
super(nrRand,self).seed(nSeed)
while nSeed < 0:
super(nrRand,self).seed(nSeed)
count -= 1
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
def setstate(self,state):
self.previous = state[0]
super(nrRand,self).setstate(state[1])
getstate and setstate only manipulate the state the Random class knows about; neither method knows that you also need to roll back the set of previously-generated numbers. You're rolling back the state inherited from Random, but then the object sees that it's already produced the next number and skips it. If you want getstate and setstate to work properly, you'll have to override them to set the state of the set of already-generated numbers.
UPDATE:
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
This shouldn't directly use self.previous. Since you don't make a copy, you're returning the actual object used to keep track of what numbers have been produced. When the RNG produces a new number, the state returned by getstate reflects the new number. You need to copy self.previous, like so:
def getstate(self):
return (self.previous[:], super(nrRand, self).getstate())
I also recommend making a copy in setstate:
def setstate(self, state):
previous, parent_state = state
self.previous = previous[:]
super(nrRand, self).setstate(parent_state)
Starting some programming with python at school now, and I don't know how to proceed with this problem. Any thoughts?
Input consists of integer separated by line breaks. Your program should submit them in a linked list, traverse the linked list and print the highest number.
Something to take the first number, and do an action which says "if the next number is bigger, take that one, else, keep the current number, and head down the list and repeat"
Then when it gets to the end of the list, it prints the value it has.
from sys import stdin
class Kubbe:
vekt = None
neste = None
def __init__(self, vekt):
self.vekt = vekt
self.neste = None
def spor(kubbe):
# WRITE YOUR CODE HERE
# Creates linked list
forste = None
siste = None
for linje in stdin:
forrige_siste = siste
siste = Kubbe(int(linje))
if forste == None:
forste = siste
else:
forrige_siste.neste = siste
# Calls the solution function and prints the result
print spor(forste)
Input: example
54
37
100
123
1
54
Required output
123
"Linked lists" are rarely used in Python -- normally, one uses just list, the Python built-in list, which is actually more of a "dynamic vector". So, it's peculiar to see a linked list specified as part of the exercise's constraints.
But the main point is, the code you're showing is already creating a linked list -- the head is at forste, and, for each node, the next-node pointer at .neste, the payload at .vekt. So, presumably, that's not what you're asking about, no matter the text of your question.
The simple way to loop through your linked list once you have fully constructed it (i.e., at the end of the current code for spor) is
current = forste
while current is not None:
...process current.vekt...
current = current.neste
In your case, the logic for the "process" part is of course, as your Q's text already says:
if current.vekt > themax:
themax = current.vekt
The only subtlety is, you need to initially set themax, before this while loop to "the lowest possible number"; in recent versions of Python, "minus infinity" is reliably recorded and compared (though only as a float, it still compares correctly to ints), so
themax = float('-inf')
would work. More elegant might be to initially set the maximum to the first payload, avoiding messing with infinity.
Here's an answer based on your own code and language. Sorry if the new variable and function names do not translate well, as I don't speak Norwegian (Google Language Tools is my friend).
Comment: Like airplane Air Traffic Control the default language of most international programming forums such as StackOverflow is English. If you use it, you are likely to get quicker, better, and more answers -- and it probably makes the question and related answers useful to the largest number of other folks. Just my 2 øre... ;-)
from sys import stdin
class Kubbe:
vekt = None
neste = None
def __init__(self, vekt):
self.vekt = vekt
self.neste = None
def spor():
# WRITE YOUR CODE HERE
# Creates linked list
forste = None
siste = None
while True:
try:
linje = raw_input()
except EOFError:
break
forrige_siste = siste
siste = Kubbe(int(linje))
if forste == None:
forste = siste
else:
forrige_siste.neste = siste
return forste
def finne_maksimal(lenketliste):
storste = None
if lenketliste is not None:
storste = lenketliste.vekt
gjeldende = lenketliste.neste
while gjeldende is not None:
if gjeldende.vekt > storste:
storste = gjeldende.vekt
gjeldende = gjeldende.neste
return storste
lenketliste = spor()
storste = finne_maksimal(lenketliste)
if lenketliste is None:
print "tom liste"
else:
print "storste er", storste
There is a builtin function in Python called reduce, which traverses a list and "compresses" it with a given function. That is, if you have a list of five elements [a,b,c,d,e] and a function f, it will effectively do
temp = f(a,b)
temp = f( temp, c )
...
You should be able to use this to write a very neat solution.
If you want to be less abstract, you will need to iterate over each element of the list in turn, storing the greatest number so far in a variable. Change the variable only if the element you have reached is greater than the value of said variable.
This seems to work with your input (works in both python 2 and 3). Notice how max works with duck typing of Python!
This version works with Python3 also from file.
import sys
class Kubbe:
vekt = None
neste = None
def __init__(self, vekt):
self.vekt = vekt
self.neste = None
def spor():
# WRITE YOUR CODE HERE
# Creates linked list
forste = None
siste = None
while True:
linje = sys.stdin.readline().rstrip()
if not linje:
break
forrige_siste, siste = siste, Kubbe(int(linje))
if forste is None:
forste = siste
else:
forrige_siste.neste = siste
return forste
def traverse(linkedlist):
while linkedlist is not None:
yield linkedlist.vekt
linkedlist=linkedlist.neste
# Calls the solution function and prints the result
linkedlist=spor()
for item in traverse(linkedlist):
print(item)
# use builtin max:
print('Maximum is %i' % max(traverse(linkedlist)))
# if not allowed:
m = linkedlist.vekt
for item in traverse(linkedlist.neste):
if item > m: m = item
print(m)
The below code would work. The Node class represents the LinkedList Node. The LinkedList class defines the methods to add node at the end of the Linked List and find_max will traverse through the list and return the node with largest key.
class Node(object):
def __init__(self, key, next_node):
self.key = key
self.next_node = next_node
class LinkedList(object):
def __init__(self):
self.head = None
def append(self, key):
# Create a new Node
new_node = Node(key, None)
if (self.head == None):
self.head = new_node
else:
tmp = self.head
while(tmp.next_node != None):
tmp = tmp.next_node
tmp.next_node = new_node
def find_max(self):
tmp = self.head
max_num = 0
while(tmp != None):
if (tmp.key > max_num):
max_num = tmp.key
tmp = tmp.next_node
return max_num