example output estimate of pi:
3.13658765
then a new better estimate comes along. Say, 3.1416232.
So I find the first character in the old estimate that doesn't match the new. In this case, it is the 4th character.
Question: Is there a way to delete the 4th character in console(and then repeat this until all characters after 3.1 are gone) so that I can then print the new, better values for each of those characters?
Note: I don't want to delete everything and console and then reprint, as this would get considerably slower as the number of digits increases.
It sounds like you want something like:
best_est = None
while True:
est = some_estimate_method() # assuming this is a 'str'
if not best_est:
best_est = est
else:
if (float(est) > float(best_est)):
best_est = est
print(best_est, end = '\r')''
Depending on the directional relation of the estimate (i.e. is less better or is more better), you would have to change the inequality to accommodate.
However, if we look at your example:
# initial print
3.13658765
# get new estimate (3.1416232)
# overwrite the print
3.1416232
You originally wanted to "re-print" 3.1 then print all the new characters in the new estimate. That begs to ask the question why not just print the whole new estimate?
Since the entire value of the new estimate is greater, that means the comparison you are looking for (starting at index 4 and beyond) has already be checked when using < or > for inequality. Simply calling a print(est, end = '\r') returns the console cursor to the beginning of the line, effectively overwriting the value each time.
If you just need to overwrite your last line, you can do something like this. The "\r" means instead of a newline, a return carriage will be printed, moving you back to the start of the same line to overwrite
print("3.1515", end="\r")
print("3.1415")
Furthermore, if you want to do tricky things, you could look into ANSI escape codes, these will let you print to any arbitrary location, although they aren't the most portable. These will also let you do fun things like setting the colour.
For example print("\033[31;1HX") would print an X to the 31's column and 1st row. To delete a character, you could simply print a space over top (print("\033[31;1H ")).
This may not work on all terminals
http://ascii-table.com/ansi-escape-sequences.php
Related
When outputting to the command line using carriage return in order to continually overwrite a single row (ex: for a progress bar) is there a way to make sure I overwrite the entire row? For example I'm running into something like:
sys.stdout.write("A really long string on output number one" + '%\r')
sys.stdout.write("Short one on next update" + '%\r')
Which leaves me with leftover "junk" at the end like:
Short one on next updateutput number one
I guess I could add a ton of spaces to the end of my output to overwrite with blank spaces but there has to be a better way?
I'm trying to write a program for a homework using recursion to search for a word in a matrix (2x2 or more), it can be going from left to right or from up to down (no other directions), for example if I am searching for ab , in the matrix [['a','b'],['c','d']], the program should return in what direction the word is written (across), the starting index(0), ending index(2), and the index of the row or column(0).
My problem is that I have the idea of the recursion but, I can't implement it. I tried to break the problem down into more little proplems, like searching for the word in a given row, I started by thinking of the smallest case which is 2x2 matrix, at the first row and column, I need to search one to the right and one to the bottom of the first char, and check if they are equal to my given string, then give my recursion function a smaller problem with the index+1. However I can't think of what to make my function return at the base case of the recursion, been trying to solve it and think of ways to do it for two days, and I can't code what I think about or draw.
Note that I can't use any loops, I would really appreciate it if somone could push me in the right direction, any help would be pretty much appreciated, thanks in advance.
Edit: more examples: for input of matrix : [['a','b','c'],['d','e','f'],['g','h','i']] the outputs are:
with the string ab : across,0,0,2
with the string be : down,1,0,2
with the string ghi: across,2,0,3
I assume that the word we are looking for could be found starting from any place but we can move up to down or left to right only.
In that case, you should have a function that takes the start index and a direction and then the function keeps moving in the given direction starting from the given index and keeps moving until it doesn't find a mismatch, and it just returns true or false based on the match of the given string.
Now you need to call this function for each and every index of the matrix along with two directions up to down and left to right, and at any index, if you get the output of the function as true then you have found your answer.
This is a very basic idea to work, next it depends on you how you want to optimize the things in this method only.
Update:
To avoid using the loops.
The other way I can think of is that the function which we have defined now takes the row, column, and the string to find. So at each call, you will first check if the character at the given row and column matches the first character of the given string if so then it calls the two more functions, one in the right direction and the other in the down direction, along with the string with the first character removed.
Now to check all the columns of the matrix, you will anyway call the function in down and right direction with the exact same string.
The base case will be that if you reach the end of the string then you have found the answer and you will return True, otherwise False.
One more thing to notice here is that if any of the 4 function calls gives you a True response then the current row/column will also return True.
Cheers!
I'm currently trying to learn python.
Suppose there was a a number n = 12345.
How would one go about changing every digit starting from the first spot and iterating it between (1-9) and every other spot after (0-9).
I'm sadly currently learning python so I apologize for all the syntax error that might follow.
Here's my last few attempts/idea for skeleton of the code.
define the function
turn n into string
start with a for loop that for i in n range(0,9) for i[1]
else range(10)
Basically how does one fix a number while changing the others?
Please don't give solution just hints I enjoy the thinking process.
For example if n =29 the program could check
19,39,49,59,69,79,89,99
and
21,22,23,24,25,26,27,28
Although you are new, the process seems far easy than you think.
You want to make that change to every digit of the number (let's say n=7382). But you cannot iterate over numbers (not even changing specific digits of it as you want to): only over iterables (like lists). A string is an iterable. If you get the way to do a int-str conversion, you could iterate over every number and then print the new number.
But how do you change only the digit you are iterating to? Again, the way is repeating the conversion (saving it into a var before the loop would make great DRY) and getting a substring that gets all numbers except the one you are. There are two ways of doing this:
You search for that specific value and get its index (bad).
You enumerate the loop (good).
Why 2 is good? Because you have the real position of the actual number being change (think that doing an index in 75487 with 7 as the actual one changing would not work well when you get to the last one). Search for a way to iterate over items in a loop to get its actual index.
The easiest way to get a substring in Python is slicing. You slice two times: one to get all numbers before the actual one, and other to get all after it. Then you just join those two str with the actual variable number and you did it.
I hope I didn't put it easy for you, but is hard for a simple task as that.
I'd like to make a simple clock (CLI) that prints the time into one line, and updates it every second. Is this even possible? Should I just print a new line every second?
This is what I have at the moment, which functions terribly:
import calendar, time
a = 1
while a == 1:
print (calendar.timegm(time.gmtime()))
If I understand, what you want to do is write the time, then, a second later, overwrite it with the new time, and so on.
On most terminals, printing a carriage return without a newline will take you back to the start of the same line. So, you can almost just do this:
print('\r{}'.format(calendar.timegm(time.gmtime())), end='')
In general, there's a problem with this: the carriage return doesn't erase the existing text, it just lets you overwrite it. So, what happens if the new value is shorter than the old one? Well, in your case, that isn't possible; you're printing a 10-digit number that can never turn into a 9-digit number. But if it were a problem, the easiest solution would be to change that {} to something like {<70}, which will pad a short line with spaces, up to 70 characters. (Of course if your lines could be longer than 70 character, or your terminal could be narrower than 70, don't use that number.)
Meanwhile, if you just do this over and over as fast as possible, you're wasting a lot of CPU and I/O, and possibly screwing up your terminal's scrollback buffer, and who knows what else. If you want to do this once per second, you should sleep for a second in between.
So:
while True:
print('\r{}'.format(calendar.timegm(time.gmtime())))
time.sleep(1)
If you want to get fancy, you can take over the whole terminal with curses on most non-Windows platforms, msvcrt console I/O on Windows, or even manually printing out terminal escape sequences. But you probably don't want to get fancy.
print function print newline (\n) after the string you passed. Specify carriage return (\r) explicitly does what you want.
To print every second, call time.sleep(1) after printing.
import calendar
import time
while 1:
print(calendar.timegm(time.gmtime()), end='\r')
time.sleep(1)
UPDATE
To make cursor remains at the end of the line, prepend \r:
print('\r', calendar.timegm(time.gmtime()), sep='', end='')
I have a massive string im trying to parse as series of tokens in string form, and i found a problem: because many of the strings are alike, sometimes doing string.replace()will cause previously replaced characters to be replaced again.
say i have the string being replaced is 'goto' and it gets replaced by '41' (hex) and gets converted into ASCII ('A'). later on, the string 'A' is also to be replaced, so that converted token gets replaced again, causing problems.
what would be the best way to get the strings to be replaced only once? breaking each token off the original string and searching for them one at a time takes very long
This is the code i have now. although it more or less works, its not very fast
# The largest token is 8 ASCII chars long
'out' is the string with the final outputs
while len(data) != 0:
length = 8
while reverse_search(data[:length]) == None:#sorry THC4k, i used your code
#at first, but it didnt work out
#for this and I was too lazy to
#change it
length -= 1
out += reverse_search(data[:length])
data = data[length:]
If you're trying to substitute strings at once, you can use a dictionary:
translation = {'PRINT': '32', 'GOTO': '41'}
code = ' '.join(translation[i] if i in translation else i for i in code.split(' '))
which is basically O(2|S|+(n*|dict|)). Very fast. Although memory usage could be quite substantial. Keeping track of substitutions would allow you to solve the problem in linear time, but only if you exclude the cost of looking up previous substitution. Altogether, the problem seems to be polynomial by nature.
Unless there is a function in python to translate strings via dictionaries that i don't know about, this one seems to be the simplest way of putting it.
it turns
10 PRINT HELLO
20 GOTO 10
into
10 32 HELLO
20 41 10
I hope this has something to do with your problem.