I want to paint some special words while the program is getting them , actually in real-time .
so I've wrote this piece of code which do it quite good but i still have problem with changing the location of the pointer with move keys on keyboard and start typing from where i moved it .
can anyone give me a hint how to do it ?
here is the CODE :
from colorama import init
from colorama import Fore
import sys
import msvcrt
special_words = ['test' , 'foo' , 'bar', 'Ham']
my_text = ''
init( autoreset = True)
while True:
c = msvcrt.getch()
if ord(c) == ord('\r'): # newline, stop
break
elif ord(c) == ord('\b') :
sys.stdout.write('\b')
sys.stdout.write(' ')
my_text = my_text[:-1]
#CURSOR_UP_ONE = '\x1b[1A'
#ERASE_LINE = '\x1b[2K'
#print ERASE_LINE,
elif ord(c) == 224 :
set (-1, 1)
else:
my_text += c
sys.stdout.write("\r") # move to the line beginning
for j, word in enumerate(my_text.split()):
if word in special_words:
sys.stdout.write(Fore.GREEN+ word)
else:
sys.stdout.write(Fore.RESET + word)
if j != len(my_text.split())-1:
sys.stdout.write(' ')
else:
for i in range(0, len(my_text) - my_text.rfind(word) - len(word)):
sys.stdout.write(' ')
sys.stdout.flush()
Doing it the easy way
As you already seem to be using the colorama module, the most easy and portable way to position the cursor should be to use the corresponding ANSI controlsequence (see: http://en.m.wikipedia.org/wiki/ANSI_escape_code)
The one you are looking for should be CUP – Cursor Position (CSI n ; m H)positioning the cursor in row n and column m.
The code would look like this then:
def move (y, x):
print("\033[%d;%dH" % (y, x))
Suffering by doing everything by hand
The long and painful way to make things work even in a windows console, that doesn't know about the above mentioned control sequence would be to use the windows API.
Fortunately the colorama module will do this (hard) work for you, as long as you don't forget a call to colorama.init().
For didactic purposes, I left the code of the most painful approach leaving out the functionality of the colorama module, doing everything by hand.
import ctypes
from ctypes import c_long, c_wchar_p, c_ulong, c_void_p
#==== GLOBAL VARIABLES ======================
gHandle = ctypes.windll.kernel32.GetStdHandle(c_long(-11))
def move (y, x):
"""Move cursor to position indicated by x and y."""
value = x + (y << 16)
ctypes.windll.kernel32.SetConsoleCursorPosition(gHandle, c_ulong(value))
def addstr (string):
"""Write string"""
ctypes.windll.kernel32.WriteConsoleW(gHandle, c_wchar_p(string), c_ulong(len(string)), c_void_p(), None)
As already stated in the comment section this attempt still leaves you with the problem, that your application will only work in the named console, so maybe you will still want to supply a curses version too.
To detect if curses is supported or you will have to use the windows API, you might try something like this.
#==== IMPORTS =================================================================
try:
import curses
HAVE_CURSES = True
except:
HAVE_CURSES = False
pass
Related
I'm very new to Python and currently am building a GUI interface in Tkinter and have a fully working code for it. I thought it would be nice to have a button work from keyboard by pressing "Enter" key.
The code line for that is:win.bind('<Return>', testButton.functionName)
Then you just put "event" in function bracket aka functionName(event) And everything works great.
The issue is that now it does not work when you press the button inside the GUI interface what means I need to duplicate and reName one of the functions to have both.
Since it is an identical code, it would make more sense to have it as a module. However, when I import my module it does not seem to see the rest of my code and claims that my variables do not exist.
Here is a simplified example of how I'm doing it.
My module saved as moduleTest:
def test():
sum = a + b
return sum
Main program:
import moduleTest
a = 10
b = 12
moduleTest.test()
print test()
It keeps claiming that a and b are not defined.
I'm clearly misunderstanding how modules work cause in my mind when I import a module it should simply import the whole code and do the same thing as this:
import moduleTest
a = 10
b = 12
def test():
sum = a + b
return sum
print test()
What am I misunderstanding and doing wrong?
Python globals are global to each module, not to the whole program.
The usual way to deal with this is to not use globals.
For your toy example, you can def test(a, b): and then call test(a, b) from your main module, and that's typically the right solution, but it isn't always appropriate.
Other options are:
Use a class, and pass the values in when you create the instance.
Store the globals that need to be shared in a third module, which both main and moduleTest can import thirdmodule and access as thirdmodule.a. This is often appropriate for cases like shared configuration values.
Store the globals as attributes of some other thing both pieces of code already have access to.
As #abarnert points out, globals are global to each module. In order to solve this problem you can use:
def test(a, b):
sum = a + b
return sum
And
import moduleTest
a = 10
b = 12
print(moduleTest.test(a, b))
I would like to point out you should not call your variables sum because this already is an existing function which you're overwriting.
Here are several separate fragments of my code to give you an idea:
item = "SNAKE"
oldString = "-" * (len(item))
blank = "-" * (len(item))
guesses = 10
def gameOn():
global guesses
global oldString
newString = ""
i = 0
x = len(item)
hanged = ""
readString = answerIn.get().upper()
winner = 1
if not readString:
if guesses == 10:
pass
else:
hanged = (HANGMAN[(len(HANGMAN) -1) - guesses])
hangedOutput.config(state=NORMAL)
hangedOutput.delete("1.0",END)
hangedOutput.insert(END,hanged)
hangedOutput.config(state=DISABLED)
error.config(state=NORMAL)
error.delete(0,END)
error.insert(0,"Please enter the value.")
error.config(state=DISABLED)
win = Tk()
answerIn = Entry(win,width = 3, border = 2)
answerIn.focus_set()
answerIn.grid(row=2, column=0, pady = 10, padx = 200, sticky = W)
win.mainloop()
When I turn it into a module it keeps asking not just for item and oldString definitions but also for answerIn, hangedOutput and etc which are part of Tkinter labels.
I would like to understand how to reprint multiple lines in Python 3.5.
This is an example of a script where I would like to refresh the printed statement in place.
import random
import time
a = 0
while True:
statement = """
Line {}
Line {}
Line {}
Value = {}
""".format(random.random(), random.random(), random.random(), a)
print(statement, end='\r')
time.sleep(1)
a += 1
What I am trying to do is have:
Line 1
Line 2
Line 3
Value = 1
Write on top of / update / refresh:
Line 1
Line 2
Line 3
Value = 0
The values of each line will change each time. This is effectively giving me a status update of each Line.
I saw another question from 5 years ago however with the addition of the end argument in Python 3+ print function, I am hoping that there is a much simpler solution.
If you want to clear the screen each time you call print(), so that it appears the print is overwritten each time, you can use clear in unix or cls in windows, for example:
import subprocess
a = 0
while True:
print(a)
a += 1
subprocess.call("clear")
If I've understood correctly you're looking for this type of solution:
import random
import time
import os
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
a = 0
while True:
clear_screen()
statement = """
Line {}
Line {}
Line {}
Value = {}
""".format(random.random(), random.random(), random.random(), a)
print(statement, end='\r')
time.sleep(1)
a += 1
This solution won't work with some software like IDLE, Sublime Text, Eclipse... The problem with running it within this type of software is that clear/cls uses ANSI escape sequences to clear the screen. These commands write a string such as "\033[[80;j" to the output buffer. The native command prompt is able to interpret this as a command to clear the screen but these pseudo-terminals don't know how to interpret it, so they just end up printing small square as if printing an unknown character.
If you're using this type of software, one hack around could be doing print('\n' * 100), it won't be the optimal solution but it's better than nothing.
You could use curses for this.
#!/usr/bin/python3
import curses
from time import sleep
from random import random
statement = """
Line {}
Line {}
Line {}
Value = {}"""
screen = curses.initscr()
n = 0
while n < 20:
screen.clear()
screen.addstr(0, 0, statement.format(random(), random(), random(), n))
screen.refresh()
n += 1
sleep(0.5)
curses.endwin()
I am running a program that works in parallel, utilizing the Pool object from the multiprocessing module.
What I am trying to do is run a function n number of times in parallel, each having a separate loading %, and I would like it to be updating the percentage for each function without replacing other percentages... example:
f(x):
while x < 0:
print 'For x = {0}, {1}% completed...\r'.format(x, percentage),
And I would run the function multiple times in parallel.
The effect I am trying to achieve is the following, for f(10000000), f(15000000), f(7000000):
For x = 10000000, 43% completed
For x = 15000000, 31% completed
For x = 7000000, 77% completed
And the percentages will be updating in their individual lines without replacing for other values of x, in this function f which will be running three times at the same time.
I tried using the carriage return '\r' but that replaces every line and just creates a mess.
Thanks for taking the time to read this post! I hope you can tell me.
I am using Python 2.7 but if it can only be achieved with Python 3 I am open to suggestions.
Curses
As #Keozon mentioned in the comments, one way to achieve this would be to use the curses library.
There is a good guide for curses on the python website.
ANSI Escape Codes
Alternatively, you might try using ANSI escape codes to move the cursor around.
This is in Python3, but it'll work just fine in any version, you'll just need to change the print statements around (or from __future__ import print_function).
print('Hello')
print('World')
print('\033[F\033[F\033[K', end='') # Up, Up, Clear line
# Cursor is at the 'H' of 'Hello'
print('Hi') # Overwriting 'Hello'
# Cursor is at the 'W' of 'World'
print('\033[E', end='') # Down
# Cursor is on the blank line after 'World'
print('Back to the end')
Output:
Hi
World
Back to the end
Edit:
I've done way too much work for you here, but hey, here's basically a full solution using the ANSI method I mentioned above:
import time
import random
class ProgressBar:
def __init__(self, name):
self._name = name
self._progress = 0
#property
def name(self):
return self._name
def get_progress(self):
"""
Randomly increment the progress bar and ensure it doesn't go
over 100
"""
self._progress += int(random.random()*5)
if self._progress > 100:
self._progress = 100
return self._progress
class MultipleProgressBars:
def __init__(self, progress_bars):
self._progress_bars = progress_bars
self._first_update = True
self._all_finished = False
#property
def all_finished(self):
"""
A boolean indicating if all progress bars are at 100
"""
return self._all_finished
def update(self):
"""
Update each progress bar
"""
# We don't want to move up and clear a line on the first run
# so we have a flag to make sure this only happens on later
# calls
if not self._first_update:
# Move up and clear the line the correct number of times
print('\033[F\033[K'*len(self._progress_bars),end='', sep='')
num_complete = 0 # Number of progress bars complete
for progress_bar in self._progress_bars:
name = progress_bar.name
progress = progress_bar.get_progress()
if progress == 100:
num_complete += 1
# Print out a progress bar (scaled to 40 chars wide)
print(
name.ljust(10),
'[' + ('='*int(progress*0.4)).ljust(40) + ']',
str(progress)+'%')
if num_complete == len(self._progress_bars):
self._all_finished = True
self._first_update = False # Mark the first update done
# Create a list of ProgressBars and give them relevant names
progress_bars = [
ProgressBar('James'),
ProgressBar('Bert'),
ProgressBar('Alfred'),
ProgressBar('Frank')
]
# Create a new instance of our MultipleProgressBars class
mpb = MultipleProgressBars(progress_bars)
# Keep updating them while at least one of them is still active
while not mpb.all_finished:
mpb.update()
time.sleep(0.2)
How would i expand upon my existing function in order to get it to try the password on a locked zip file
chars = "abcdefghijklmnopqrstuvwxyz"
password = "hello"
def brute_force(x, y):
#Where x stands for chars(list to check in) and y stands for password variable to check against
for length in range(1, 100):
to_attempt = product(x, repeat=length)
for attempt in to_attempt:
i = i + 1
if ''.join(attempt) == y:
print('Password: ' + ''.join(attempt))
return
I won't completely re-write your function for you, but to test each attempt you would do (import zipfile at the top):
f = zipfile.ZipFile('path/to/file')
for attempt in attempts:
try:
f.extractall(pwd=attempt)
except RuntimeError:
continue
else:
return attempt
def brute_force(x, y):
#since you already have the password just return it
return y
ok ok that probably wasnt the answer you are looking for ...
but really the only way I know of(assuming you dont know an exploit to decode whatever encryption this might be) is to brute force it...
of coarse many systems have vunerabilities you can exploit to gain access without necessarilly "guessing " the password
if you are asking how can you not include y and instead test it against a real file try the zipfile module , which includes a password option for most methods
using zipfile module
import zipfile
z = zipfile.Zipfile('your_zip_file')
def searching(z,x):
try:
z.extractall(pwd=x)
print "\n[+]Password found: " + x
exit
except:
pass
# loop over you combination call searching
searching(z,pwd)
This might will help you. you can use concept of threading to make it faster
Why am i getting an "invalid syntax" when i run below code. Python 2.7
from string import *
def countSubStringMatch(target,key):
counter=0
fsi=0 #fsi=find string index
while fsi<len(target):
fsi=dna.find(key,fsi)
if fsi!=-1:
counter+=1
else:
counter=0
fsi=fsi+1
fsi=fsi+1
#print '%s is %d times in the target string' %(key,counter)
def countSubStringMatch("atgacatgcacaagtatgcat","atgc")
In the line:
def countSubStringMatch("atgacatgcacaagtatgcat","atgc")
You should remove the def. def is used when defining a function, not when calling it.
for string count you could just do:
target = "atgacatgcacaagtatgcat"
s = 'atgc'
print '%s is %d times in the target string' % (s, target.count(s))
Other things wrong with your code:
You don't use and don't need anything in the string module. Don't import from it.
Don't do from somemodule import * unless you have a very good reason for it.
Your code rather slowly and pointlessly struggles on after the first time that find returns -1 ... your loop should include
if fsi == -1: return counter
so that you return immediately with the correct count.
Be consistent: you use counter += 1 but fsi = fsi + 1
... which reminds me: find 'PEP 8' (style guide) at www.python.org, and read it -- your space bar must be feeling unloved ;-)
HTH
John