In which we are strung along with a string of 1s and 0s.
Have you ever had occasion to generate all possible bit combinations of a certain length? Perhaps you are working through Jeffrey Ullman's Automata class on Coursera or futzing about with crypto/encodings/etc. and need all the possible combinations for testing some brilliant algorithm you have been working on. I do not remember what I was working on the last two times I implemented this (the above are logical guesses); however, I am posting it so I will not have to do it a third time.
import itertools
def kbits(n, k):
bit_patterns = []
# generate all possible k positions to set to 1
for bits in itertools.combinations(xrange(n), k):
# create a string of all 0 of the proper length
s = ['0'] * n
# set the chosen positions to 1
for bit in bits:
s[bit] = '1'
# rinse and repeat for all possible positions
bit_patterns.append(''.join(s))
return bit_patterns
def generate_bit_patterns(length):
bit_patterns = []
# starting with no bits set to 1
# create strings with an increasing number of bits set to 1
# until all bits are set to 1
for i in xrange(length + 1):
bit_patterns.extend(kbits(length, i))
return bit_patterns
Usage is simple.
generate_bit_patterns(3)
which will result in
['000', '100', '010', '001', '110', '101', '011', '111']
Note: the implementation of kbits is similar to the one here, and it is entirely likely to be what I started with.
[UPDATE 16APR2014]
As pointed out by grubernd in the comments, if you are generating long bit patterns, you should probably do it with a generator to conserve resources. Here is my original and perhaps harder to understand attempt.
def bit_pattern(length, set_bits):
pattern = ['0'] * length
for i in set_bits:
pattern[i] = '1'
return ''.join(pattern)
def bit_range(length):
return (bit_pattern(length, bits)
for i in xrange(length + 1)
for bits in itertools.combinations(xrange(length), i))
To test this try
for b in bit_range(3):
print b
which will result in
000
100
010
001
110
101
011
111
In which we do things we never wanted to do with VBA - merge sheets from several Excel workbooks into a single workbook.
A coworker came to me a few days ago needing to merge a directory full of Excel workbooks into a single workbook to provide to a 3rd party. Apparently each workbook is an extract/report of some sort, but the process that generates the files is unable to consolidate the report output into individual sheets in a single workbook. What we have below is a quick and dirty macro I wrote to get the job done.
Problem:
You have a directory full of Excel workbooks
Each workbook has a single sheet containing data
You would like to consolidate the sheets into a single workbook
Solution:
Ensure all the workbooks are in the same directory
Open Excel
Press Alt + F11 to open Microsoft Visual Basic for Applications
Double click on ThisWorkbook on the left side under Projet - VBAProject
Paste the code below into the editor
Update the line path = "PATH TO YOUR EXCEL WORKBOOKS" by typing the path to your workbooks inside the quotes
Place your cursor anywhere inside the mergeWorkbooks() subroutine
Press F5 or click the green play button
When complete, you can close Microsoft Visual Basic for Applications
The open workbook will contain your merged data
Notes:
The comments indicate the variables you can change to adjust the range of columns to copy data from.
The final row is set to 65536 because I was working with workbooks in legacy format - adjust if you are using workbooks with more rows.
removeBlankSheets() is used to remove the original 3 sheets inserted by Excel when a workbook is opened as well as any other blank sheets. It does so by checking if the first cell is blank. You may need to adjust/remove this depending on your data.
Sub mergeWorkbooks()
Dim path As String
Dim startCol As String
Dim startCell As Integer
Dim endCol As String
' Path to currentWorkbook
path = "PATH TO YOUR EXCEL WORKBOOKS"
' Set to Start Column
startCol = "A"
' Set to Start Cell
startCell = 1
' Set to End Column
endCol = "IV"
' Keep a reference to the workbook we want to merge into
Dim mainBook As Workbook
Set mainBook = ThisWorkbook
Dim currentWorkbook As Workbook
Dim fileSystem As Object
Dim directory As Object
Dim files As Object
Dim file As Object
Application.ScreenUpdating = False
Set fileSystem = CreateObject("Scripting.FileSystemObject")
Set directory = fileSystem.Getfolder(path)
Set files = directory.files
For Each file In files
Set currentWorkbook = Workbooks.Open(file)
Range(startCol & startCell & ":" & endCol & Range(startCol & "65536").End(xlUp).Row).Copy
' Add a worksheet to paste into
' Who thought the syntax for after was a good idea?
mainBook.Worksheets.Add After:=Worksheets(mainBook.Worksheets.Count)
mainBook.Worksheets(mainBook.Worksheets.Count).Activate
Range(startCol & "65536").End(xlUp).PasteSpecial
Application.CutCopyMode = False
currentWorkbook.Close
Next
' Cleanup the sheets
ThisWorkbook.removeBlankSheets
ThisWorkbook.reNumberSheets
End Sub
Sub removeBlankSheets()
' Don't bother us
Application.DisplayAlerts = False
Dim sheet As Worksheet
For Each sheet In Worksheets
If sheet.Range("A1").Value = "" Then
sheet.Delete
End If
Next sheet
Application.DisplayAlerts = True
End Sub
Sub renumberSheets()
' Don't bother us
Application.DisplayAlerts = False
For i = 1 To ThisWorkbook.Worksheets.Count
Sheets(i).Name = "Sheet" & i
Next i
Application.DisplayAlerts = True
End Sub