PyQt: Pop previous commands from UndoStack during current command's undo - python-3.x

I'm in a situation in which I have several commands of the same class pushed onto a QUndoStack and depending on user input another command of a different class might be pushed on top of those. What I would now like to achieve is to remove a fixed number of these previous commands of the first type from the undo stack (either by undoing them or just removing them, doesn't matter in my case) when the topmost command's undo is executed. E.g. like this:
class CommandA(QUndoCommand):
# ...
class CommandB(QUndoCommand):
def undo(self):
# ...
# somehow remove last N commands of class A from undostack
stack = QUndoStack()
stack.push(CommandA())
# ...
stack.push(CommandA())
stack.push(CommandB())
Just removing the last N commands regardless of which class they belong to would also be helpful as a starting point. This seems to me like it would be a common requirement but I don't see if/how this would be possible.

In PyQt5, commands on the QUndoStack are stored by index and accessed via the command function. You can loop over the commands in the stack using the count method:
for ndx in range(stack.count()):
command = stack.command(ndx)
The command will have the type of your specific QUndoCommand class (i.e. either CommandA or CommandB), so you can use isinstance to check which one it is.
Hence, you can make a QWidget (e.g. a QtWidgets.QPushButton) or QAction whose triggered signal is connected to a function (slot) that undoes the last n CommandA commands:
def undo_last_n_CommandAs(n):
for ndx in range(stack.count()):
command = stack.command(ndx)
if n > 0 and isinstance(command, 'CommandA'):
command.undo()
n -= 1

Related

Issues utilizing return value from out stream external process

I have been banging my head on the keyboard long enough and succumb to ask for help on this matter. I am trying to execute a process in a groovy script that would run on a Linux box. So far I am able to receive a return of a number.
def proc1 = 'grep -o -i ERROR| analysis.tmp'.execute()
def proc2 = 'wc -l'.execute()
proc1 | proc2
proc2.waitFor()
This allows me to see the number of instances on that *.tmp file.
The variable below return a number as expected, fine so far.
${proc2.text}
>3818
The issue becomes when trying to create an if statement, the variable as it stands has a format that I am not able to operate comparisons with.
What have I tried?
Tried to place this value into an integer variable - failed
Tried to place this value into another String, and then modify it to an integer - that also failed.
I am just running out of google searches for the solution.

How can I make a variable dynamically change while on console python3

I am working on a program and it needs to display the number of seconds that passed since it started. The variable is inside input() like this:
while True:
something = input(str(x) + "seconds have passed. Please input the number in 60 seconds:")
if x == 60:
break
Is there any way to make the x change dynamically while on screen? So it raises every second and also updates on screen without the need to press enter.
If yes, is there also a way to add an if statement that checks when the variable reached 60 and break the loop.

TaskWarrior automatically modify UDA

I have a question. Let's say that I have created User Defined Attribute attr with values A,B,C.
How to configure taskwarrior to automatically change the attr value from A to B when I enter
task x start
and change attr from B to C when
task x done
Disadvantage of suggested solution:
You continuously need to have a script running in the background.
There can occur a small delay between your task x start command, and the change of UDA attr
It is a bit of a tedious method, perhaps you can also accomplish your goal using solely taskwarrior commands/settings.
It is made for fun and I can currently not offer any security or proper functioning guarantees. I tested and use it on WSL Ubuntu 16.04.
Assumptions:
If you enter task x start the attribute Start is set to a valid date.
Solution:
You can have a script running in the background that reads the properties of all tasks, and as soon as it detects a valid date in the Start attribute of a tasks, and a value of B in the UDA attr then it sets the UDA attr to C by executing the command task x modify attr:C command.
I made a script/small project that sorts on a custom setting of project and urgency, and it contains the functionalities of:
Running in the background from startup automatically,
Scanning the taskproperties and automatically applying the changes that are programmed in the script.
So in effect,
You should modify/add the UDA attr here:
And duplicate and change for example method private static void setCustomSort(ArrayList<Task> taskList) {1 on line 88 of the main
(For the 2nd step, between //get uuid and //create command you should add the condition that checks the task for a valid id. Then if it has, change the command that is generated to task modify attr:C)
The instructions to compile the java code and set up automation are listed here.

Liquidsoap not identifying variable clearly defined

Alright, I've been puling my hair out for hours
Liquidsoap just isn't working for me, and I know this should work, sub for one appearently obvious error...
set("log.file",false)
set("log.stdout",true)
set("log.level",3)
podcasts = playlist("/home/user/icecast/ham.txt")
# This function turns a fallible
# source into an infallible source
# by playing a static single when
# the original song is not available
def my_safe(radio) =
# We assume that festival is installed and
# functional in liquidsoap
security = single("say:Hello, we are currently having some technical difficulties but we'll be back soon so stay tuned!")
# We return a fallback where the original
# source has priority over the security
# single. We set track_sensitive to false
# to return immediately to the original source
# when it becomes available again.
fallback(track_sensitive=false,[radio, security])
end
radio= podcasts
radio= my_safe(podcasts)
# A function that contains all the output
# we want to create with the final stream
def outputs(s) =
# First, we partially apply output.icecast
# with common parameters. The resulting function
# is stored in a new definition of output.icecast,
# but this could be my_icecast or anything.
output.icecast = output.icecast(host="localhost", password="foobar")
# An output in mp3 to the "live" mountpoint:
output.icecast(%mp3, mount="live",radio)
end
And the error
At line 23, character 6: The variable radio defined here is not used anywhere
in its scope. Use ignore(...) instead of radio = ... if you meant
to not use it. Otherwise, this may be a typo or a sign that your script
does not do what you intend.
If someone could also fix another issue I'm having
I would like to find how to run two sources to two separate mountpoints
set("log.file",false)
set("log.stdout",true)
set("log.level",3)
podcasts = playlist("/home/user/icecast/ham.txt")
songlist = playlist("/home/user/icecast/otherplaylist.txt")
# This function turns a fallible
# source into an infallible source
# by playing a static single when
# the original song is not available
def my_safe(radio) =
# We assume that festival is installed and
# functional in liquidsoap
security = single("say:Hello, we are currently having some technical difficulties but we'll be back soon so stay tuned!")
# We return a fallback where the original
# source has priority over the security
# single. We set track_sensitive to false
# to return immediately to the original source
# when it becomes available again.
fallback(track_sensitive=false,[radio, security])
end
radio= podcasts
radio= my_safe(podcasts)
def my_safe(songlist) =
# We assume that festival is installed and
# functional in liquidsoap
security = single("say:Hello, we are currently having some technical difficulties but we'll be back soon so stay tuned!")
# We return a fallback where the original
# source has priority over the security
# single. We set track_sensitive to false
# to return immediately to the original source
# when it becomes available again.
fallback(track_sensitive=false,[songlist, security])
end
moarradio= songlist
moarradio= my_safe(songlist)
# A function that contains all the output
# we want to create with the final stream
def outputs(s) =
# First, we partially apply output.icecast
# with common parameters. The resulting function
# is stored in a new definition of output.icecast,
# but this could be my_icecast or anything.
output.icecast = output.icecast(host="localhost", password="foobar")
# An output in mp3 to the "live" mountpoint:
output.icecast(%mp3, mount="live",radio)
output.icecast(%mp3, mount="otherlive",moarmusic)
end
And I get the same error, but it tells me the second variable isn't used (moarradio)
The liquidsoap configuration file is basically a script, which means it will be run from top to bottom.
Upon reading the configuration file, it is complaining that you are not using the radio variable defined line 23, the reason being you are using the one defined line 24. Unlike many other languages, there are no assignments, only definitions in a liquidsoap script
Other than that, you seem to not understand the difference between global and local variables, and their respective scopes.
You are declaring a my_safe function, which takes an argument. Within the scope of the function, refer to your argument with its name. Then call the my_safe function with your global variables as the argument, and what you are expecting will actually happen.
Your sources will not get registered if you do not call the outputs function. Simply drop the function construct.
Here is how I rewrote your second example:
set("log.file",false)
set("log.stdout",true)
set("log.level",3)
podcasts = playlist("/home/user/icecast/ham.txt")
songlist = playlist("/home/user/icecast/otherplaylist.txt")
# This function turns a fallible
# source into an infallible source
# by playing a static single when
# the original song is not available
def my_safe(stream) = # <- used a different variable name here
# We assume that festival is installed and
# functional in liquidsoap
security = single("say:Hello, we are currently having some technical difficulties but we'll be back soon so stay tuned!")
# We return a fallback where the original
# source has priority over the security
# single. We set track_sensitive to false
# to return immediately to the original source
# when it becomes available again.
fallback(track_sensitive=false,[stream, security]) # <- used a different variable name here
end
radio= my_safe(podcasts) # <- fix here
# <- got rid of redeclaration of my_safe
moarradio= my_safe(songlist) # <- fix here
# <- got rid of function construct
# First, we partially apply output.icecast
# with common parameters. The resulting function
# is stored in a new definition of output.icecast,
# but this could be my_icecast or anything.
output.icecast = output.icecast(host="localhost", password="foobar")
# An output in mp3 to the "live" mountpoint:
output.icecast(%mp3, mount="live",radio)
output.icecast(%mp3, mount="otherlive",moarradio) # <- fix here

How do I apply command line overrides to SystemVerilog ovm_sequence objects?

I'd like to apply a command line override to an ovm_sequence object like this:
+ovm_set_config_int=*,max_timeout,100000
The max_timeout field is declared inside ovm_sequence_utils macro.
Is there any way to do it? My understanding is that ovm sequences are not part of the ovm hierarchy, so perhaps they can't be modified from the command line.
I'm not aware of a mechanism that lets you set-up config space like that from the command line. A quick grep of the OVM source doesn't show anything either.
A quick comment on
ovm sequences are not part of the ovm hierarchy
They're not constructed at build time, that's correct. They are created just before they start running on a sequencer, but any ovm_object based class can interrogate a config integer via get_config_int()
Normally I'd use a plus-arg for things like this, and the set the config int in my base test class based on that plus-arg. For example, the command line would have:
+max_timeout=100000
...and then, in my base test class, which all my tests inherit from:
function void build();
int timeout;
[....]
if ($value$plusargs("max_timeout=%d", timeout)) begin
`ovm_info(get_type_name(), "Setting timeout", OVM_MEDIUM);
set_config_int("*", "max_timeout", timeout");
end
[....]
endfunction
Normally my uses are not quite so literal as that, having flags that set multiple values up, but that's the basics of it.
I got it working (following instructions from http://www.testbench.in/OT_10_OVM_SEQUENCE_5.html) by adding the following to my ovm_sequence in task body():
if(!(p_sequencer.get_config_int("max_timeout",max_timeout)))
max_timeout = ... // some default value
The key here is that the command line config needs to be set for the sequencer, and the sequence can pick up that config using the above-mentioned code.

Resources