1

I have a function that works exactly how I want it to, but for my course work, I have to turn this function into a class that:

  • Must have a function called solveIt,
  • returns the following two values:
    • a boolean that is True if you've solved this knapsack problem, and
    • the knapsack object with the correct values in it.

The class must have a __str__() function that returns a string like this. The first line is the size, and the second is a comma-separated list of the elements:

10 4,1,9,2,0,4,4,4,3,7 

I dont understand classes that well, so any help will be appreciated. Here is the function I have right now:

from itertools import combinations def com_subset_sum(seq, target): if target == 0 or target in seq: print(target) return True for r in range(len(seq),1,-1): for subset in combinations(seq, r): if sum(subset) == target: print(subset) return True return False print(com_subset_sum([4,1,9,2,0,4,4,4,3,7],10)) 
6
  • 1
    Does this need to be a class? I mean, functions rock. Commented Apr 18, 2013 at 0:46
  • If it is for a course, they are usually pretty insistant Commented Apr 18, 2013 at 0:48
  • yeah trust me i wish it didnt have to be a class but the instructor made it mandatory to make it a class. i figured if i made a function first i could maybe understand how to make a class on my own but avast i had no luck and im completely lost Commented Apr 18, 2013 at 0:50
  • Do you have any more information from the instructor than just "make a class that…"? If you were going to add multiple different operations to a knapsack object, for example, that would be a good reason to make a Knapsack class. Or, if you wanted to be able to evaluate the same sequence with a variety of different targets, and maybe keep track of all the targets you've checked for. Or… there are lots of good reasons. Of course, there's one all-too-common bad reason: an instructor who has no idea how to write a good assignment. But I don't want to just assume that… Commented Apr 18, 2013 at 0:54
  • yeah there are some more instruction but they dont explain much outside of what i have here they are if you want to see: i.imgur.com/67X6u4o.png Commented Apr 18, 2013 at 1:09

1 Answer 1

1

One obvious way to transform a function to a class is to turn the function parameters (or some of them) into object attributes. For example:

class Knapsack(object): def __init__(self, seq, target): self.seq = seq self.target = target self.solution = None def solveIt(self): if self.target == 0 or self.target in self.seq: self.solution = (target,) return True, self.solution for r in range(len(self.seq),1,-1): for subset in combinations(self.seq, r): if sum(subset) == self.target: self.solution = subset return True, self.solution return False, () 

Now you can do this:

>>> knapsack = Knapsack([4,1,9,2,0,4,4,4,3,7],10) >>> print(knapsack.solveIt()) (True, (4, 1, 2, 0, 3)) 

And then, adding a __str__ method is simple:

def __str__(self): if self.solution is None: self.solveIt() return '{}\n{}'.format(len(self.seq), ','.join(map(str, self.solution))) 

The reason I added that self.solution is so that calling __str__ over and over won't keep calculating the results over and over. You could just as easily drop that member and write this:

def __str__(self): solved, solution = self.solveIt() return '{}\n{}'.format(len(self.seq), ','.join(map(str, solution))) 

Either way, I'm not sure how this is better than the function. (In fact, it's strictly worse: with the function, you can always use functools.partial to bind in just the sequence, or both the sequence and the target, or of course bind in neither, whereas with the class, you always have to bind in both.)

Maybe your professor has given you some kind of hints on how you'd want to use this object that might help? Or maybe your professor is just an idiot who doesn't know how to come up with a good motivating assignment for teaching you about classes…

Sign up to request clarification or add additional context in comments.

6 Comments

thanks for the help however when i true to run to code it gives me the error: "global name combinations is not defined
You still need the from itertools import combinations at the start. I assumed you understood import if you were able to write the function…
alright thought i had that in there when i ran it sorry im dumb. and is there a way you can make the solution print out like i have up top with the target on the first line and then the solution set on the line below seperated by commas?
I thought by "size" you meant len(seq). If you want the target instead, just change len(self.seq) to self.target. Beyond that… it already does what you're asking for. Have you actually tried it?
yeah i ran it and it out put this:(True, (4, 1, 2, 0, 3))
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.