def set_all_off_except_last_k_positions(bitstring, k): """if the bitstring is 1001011, we want to keep the last two places, which is 11 intact and set previous positions to 0: (x & ((1 << k) - 1)) because, 1<<k means there are k zeros after a 1. Example: 1 << 3 = 1000. 1000 - 1 = 111 so this will keep the last k places intact and set other places to zero. """ shifted_one = create_and_shift_ones(bitstring, k) # create a bitarray of 1 and shift it left k times str_len = len(bitstring) # this length doesn't include '0b' shifted_one_minus_one = bin(shifted_one.int - 1)[2:] # subtract 1 from the shifted 1, so that all bits are 1s diff = len(bitstring) - len(shifted_one_minus_one) # this much 0s are needed to make them of equal lenght equal_length_ones = BitArray('0b' + '0' * diff + shifted_one_minus_one) return equal_length_ones.__and__(bitstring) # now we can perform the AND operation