Skip to content

Instantly share code, notes, and snippets.

@fire-eggs
Last active April 2, 2016 01:59
Show Gist options
  • Save fire-eggs/7322c5debeaf945a8d570d5b91e86e00 to your computer and use it in GitHub Desktop.
Save fire-eggs/7322c5debeaf945a8d570d5b91e86e00 to your computer and use it in GitHub Desktop.
A bin packer script. I use it to efficiently pack folders of stuff for DVD burning. It does not handle recursive folders: only files in 'top level' folders.
import math
import os
from os.path import join, getsize, isfile, isdir
def as_blocks(val):
return math.ceil(val/2048.0) # dvd block size
def getKey(item):
return item[1]
class Bin(object):
''' Container for items that keeps a running sum '''
def __init__(self):
self.items = []
self.sum = 0
def append(self, item):
self.items.append(item)
self.sum += item[1]
def __str__(self):
''' Printable representation '''
return 'Bin(sum=%d, items=%s)' % (self.sum, str(self.items))
# total blocks on DVD: 2295104
db = []
# treat files as a 'box'
# treat one level of subdirectories as a 'box'
#mypath = 'e:/to_backup/software'
mypath = 'r:/anime/@to_burn'
for foo in os.listdir(mypath):
fullpath = join(mypath, foo)
if os.path.isfile(fullpath):
db.append( (foo, as_blocks(getsize(fullpath))))
else:
db.append( (foo, as_blocks(sum(getsize(join(fullpath, subnames)) for subnames in os.listdir(fullpath)))))
for bar in db:
print( "Box: ", bar[0], "Size:", bar[1] )
# bin pack
BIN_SIZE = 2295104 # total blocks on DVD
# sort the items BY SIZE
items = sorted(db, key=getKey)
print ("Sorted:")
for bar in items:
print( "Box: ", bar[0], "Size:", bar[1] )
bins = []
while (len(items) > 0):
x = items.pop()
placed = False
for b in bins:
if (b.sum + x[1] < BIN_SIZE):
b.append(x)
break
else:
bin = Bin()
bin.append(x)
bins.append(bin)
for b in bins:
print(b)
if (b.sum > BIN_SIZE):
print('Too large for DVD')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment