Memory Error when trying to brute force a key - python-2.7

def bruteForce( dictionary = {}):
key = 0
for i in range(len(dictionary)):
keyRank = 0
for k in range(68719476736):
attempt = decrypt(dictionary[i], k)
if(i != attempt):
keyRank = 0
break
else:
keyRank += 1
key = k
print 'key attempt: {0:b}'.format(key)
if(keyRank == len(dictionary)):
print 'found key: {0:b}'.format(key)
break
The key is 36 bits
I get a memory error on the for k in range() line of code
Why is this a memory issue? Does python build an actual list of ints before running this line? Is there a better way to write this loop?
I'm brand new to Python and this wouldn't be a problem in C or Java.
This is a known-plaintext/ciphertext attack. dictionary is a mapping of P:C pairs.
Its on a VM, I can up the memory if needed, but want to know both why its failing and a code-based workaround or better idiomatic approach.

In python 2, range() will build the entire list in memory.
xrange() is a sequence object that evaluates lazily.
In python 3, range() does what xrange() did.

Related

recursive binary search using python 2.7

Wrote this code in comp sci class and I cant get it to work, it always returns as false every time I run it. Its supposed to be a recursive binary search method... Any idea why it only returns false?
arr = [1,10,12,15,16,122,132,143,155]
def binarysearch(arr,num):
arr2 = []
if (len(arr) == 1):
if (arr[0] == num):
return 1
else:
return 0
for i in range (len(arr)/2):
arr2.append(0)
if (arr[len(arr)/2]>num):
for x in range (len(arr)/2,len(arr)):
arr2[x-(len(arr)/2)]=arr[x]
return binarysearch(arr2,num)
if(arr[len(arr)/2]<num):
for x in range(0, len(arr) / 2 ):
arr2[x] = arr[x]
return binarysearch(arr2, num)
num = raw_input("put number to check here please: ")
if(binarysearch(arr,num)==1):
print "true"
else:
print "false"
You're doing vastly more work than you need to on things that Python can handle for you, and the complexity is masking your problems.
After your base case, you have two if statements, that don't cover the full range—you've overlooked the possibility of equality. Use if/else and adjust the ranges being copied accordingly.
Don't create a new array and copy stuff, use Python's subranges.
Don't keep repeating the same division operation throughout your program, do it once and store the result.
If you want to print True/False, why not just return that rather than encoding the outcome as 0/1 and then decoding it to do the print?
Recall that raw_input returns a string, you'll need to convert it to int.
The end result of all those revisions would be:
def binary_search(arr,num):
if (len(arr) == 1):
return (arr[0] == num)
mid = len(arr) / 2
if (arr[mid] > num):
return binary_search(arr[:mid], num)
else:
return binary_search(arr[mid:], num)
num = int(raw_input("put number to check here please: "))
print binary_search(arr,num)

Write a function that calculates the sum of all values in a list of integers that are both positive and even

The function should accept a single list as a parameter. The function should return an integer value as the result of calculation. If there are no positive and even integer values in the list, your function should return 0.
My current code:
def main():
print (sum_positive_even([1,2,3,4,5]))
print (sum_positive_even([-1,-2,-3,-4,-5]))
print (sum_positive_even([1,3,5,7,9]))
def sum_positive_even(list):
for num in list:
if num < 0:
list.remove(num)
for num in list:
if num % 2 == 1:
list.remove(num)
result = sum(list)
return result
main()
The output should be like:
6
0
0
I'm confused where I should put the 'return 0'.
Thanks TA!
Deleting from a list while you iterate over it is a Bad Idea - it's very easy to get hard-to-track-down bugs that way. Much better would be to build a new list of the items you want to keep. You don't need a special case of returning 0; the general approach should be able to handle that.
Also, it's better not to use list as a variable name in Python, because that's the name of a built-in.
A modification of your approach:
def sum_positive_even(lst):
to_keep = []
for num in lst:
if num > 0 and num % 2 == 0:
to_keep.append(num)
return sum(to_keep)
Since the sum of an empty list is 0, this covers the case where there are no positive even numbers.

Python / print and assign random number every time

I'm trying to generate a random integral and assign it to the variable.
import random
import time
Op = lambda: random.randint(1300, 19000)
op = "https://duckduckgo.com/html?q="
variable = int(Op())
grow = 0
while x < 3:
print(Op())
grow = grow + 1
time.sleep(1)
In here everything works fine, function "print" prints different result every time with 3 attempts.
However when I want to format this code like this:
Op = lambda: random.randint(1300, 19000)
op = "https://duckduckgo.com/html?q="
Op1 = int(Op())
pop = str("{}{}").format(op, Op1)
grow = 0
while grow < 3:
print(pop)
grow = grow + 1
time.sleep(1)
Then the function print gives me the same number three times.
For example:
>>>https://duckduckgo.com/html?q=44543
>>>https://duckduckgo.com/html?q=44543
>>>https://duckduckgo.com/html?q=44543
And I would like to get three random numbers. For example:
>>>https://duckduckgo.com/html?q=44325
>>>https://duckduckgo.com/html?q=57323
>>>https://duckduckgo.com/html?q=35691
I was trying to use %s - %d formatting but the result is the same.
Because you never changes the value of 'pop'.
In you first example you are creating instance of Op in every iteration but in second example you created instance once outside the loop and print the same value.
Try this:
Op = lambda: random.randint(1300, 19000)
op = "https://duckduckgo.com/html?q="
grow = 0
while grow < 3:
pop = str("{}{}").format(op, int(Op()))
print(pop)
grow = grow + 1
time.sleep(1)
Lambda functions are by definition anonymous. If you need to "remember" a lambda's procedure, just use def statement. But actually you don't even need this:
import random
import time
url_base = "https://duckduckgo.com/html?q={}"
grow = 0
while grow < 3:
print(url_base.format(random.randint(1300, 19000))
grow = grow + 1
time.sleep(1)
Your main problem is that you are trying to assign fixed values to variables and expect them to behave like procedures.
You need to apply randomness at every iteration. Instead you calculate a random number once and plug it in to every loop.

please help, python table file find max value

please help
I'm a beginner to python programming and my problem is this:
I have to make a program which first reads a text file like this one->
A a 1 2 (line one)
A b 3 5 (line two)
A c 9 1
B d 2 4
B e 9 2
C r 3 4
...
and find out: for each First Value (A, B, C, ...), which second value (a, b, c, ...) has max (third value)*(fourth value) (1*2, 3*5, ...) value.
that is, in this example the result should be b, e, r.
And I need to do it 1) without using dictionary class and saving each data
or 2) devise a class and object and do the same thing.
(actually I have to make this program twice by using either methods)
What I'am really confused about is... I made this program first by using dictionary, but I have no idea how to do it with any of those two certain methods mentioned above.
I did this by making dictionary[dictionary[value]] format and (saving each line's data), and found out which one has max value for first value.
How can I do this not on this particular way?
Especially is it even possible to do this on method 1)? (without using dictionary class and saving each data)
thank you for reading my question
I'm really just beginning to learn about this programming and if any of you could give me some advice it would be really appreciated
here is what I've done so far:
The below code works by storing the maximum values and doing comparisons with the values currently being read from the file. This code is not complete as it does not intentionally handle instances where two of the products are the same and it also does not handle an edge case that you should be able to find using your example inputs. I've left those for you to complete.
max_vals = []
with open('FILE.TXT', 'r') as f:
max_first_val = None
max_second_val = None
max_prod = 0
for line in f:
vals = line.strip('\n').split(' ')
curr_prod = int(vals[2]) * int(vals[3])
if vals[0] != max_first_val and max_first_val is not None:
max_vals.append(max_second_val)
max_first_val = vals[0]
max_prod = 0
if curr_prod > max_prod:
max_first_val = vals[0]
max_second_val = vals[1]
max_prod = curr_prod

Limit size of a list in python

I want to limit the size of a list in python 2.7 I have been trying to do it with a while loop but it doesn't work
l=[]
i=raw_input()//this is the size of the list
count=0
while count<i:
l.append(raw_input())
count=count+1
The thing is that it does not finish the loop. I think this problem has an easy answer but I can't find it.
Thanks in advance
I think the problem is here:
i=raw_input()//this is the size of the list
raw_input() returns a string, not an integer, so comparisons between i and count don't make sense. [In Python 3, you'd get the error message TypeError: unorderable types: int() < str(), which would have made things clear.] If you convert i to an int, though:
i = int(raw_input())
it should do what you expect. (We'll ignore error handling etc. and possibly converting what you're adding to l if you need to.)
Note though that it would be more Pythonic to write something like
for term_i in range(num_terms):
s = raw_input()
l.append(s)
Most of the time you shouldn't need to manually keep track of indices by "+1", so if you find yourself doing it there's probably a better way.
That is because i has a string value type, and int < "string" always returns true.
What you want is:
l=[]
i=raw_input() #this is the size of the list
count=0
while count<int(i): #Cast to int
l.append(raw_input())
count=count+1
You should try changing your code to this:
l = []
i = input() //this is the size of the list
count = 0
while count < i:
l.append(raw_input())
count+=1
raw_input() returns a string while input() returns an integer. Also count+=1 is better programming practice than count = count + 1. Good luck