I have a wx.Dialog with a custom validation process that runs after the OK button is pressed. If the validation fails I would like to shake the wx.Dialog to let users know that something is wrong with the given input.
Is there something like this implemented in wxPython?
The simplest way, would be activate a wx.Timer with a short interval that moves the dialog's position, when the processing fails.
Something like this:
import wx
class Busy(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent, wx.ID_ANY, "Busy", size= (420,240))
self.panel = wx.Panel(self,wx.ID_ANY)
self.label = wx.StaticText(self.panel, label="Processing..................", pos=(120,20))
self.gauge = wx.Gauge(self.panel,size=(300,25),pos=(80,80))
self.livelabel = wx.StaticText(self.panel, label="Time to live:", pos=(80,110))
self.lltime = wx.StaticText(self.panel, label="10", pos=(160,110))
self.closeButton =wx.Button(self.panel, label="Cancel", pos=(180,160))
self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
self.Bind(wx.EVT_CLOSE, self.OnQuit)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.lifetimer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnLifeTimer, self.lifetimer)
self.lifetimer.Start(1000)
self.life = 10
self.Show()
self.alt_pos = False
def OnTimer(self, event):
curr_pos_x, curr_pos_y = self.GetPosition()
if self.alt_pos:
self.Move(curr_pos_x+2, curr_pos_y)
self.alt_pos = False
else:
self.Move(curr_pos_x+-2, curr_pos_y)
self.alt_pos = True
def OnLifeTimer(self, evt): #Update time to live
self.gauge.Pulse()
self.life -= 1
self.lltime.SetLabelText(str(self.life))
if self.timer.IsRunning() or self.life > 0:
return
else:
self.label.SetLabel("Timed Out")
self.timer.Start(50)
def OnQuit(self, event):
self.timer.Stop()
self.lifetimer.Stop()
self.result_text = None
self.EndModal(False)
app = wx.App()
dlg = Busy(parent = None)
result = dlg.ShowModal()
print (result)
if result:
print (dlg.result_text)
else:
print ("Dialog Cancelled")
dlg.Destroy()
Related
I am currently working on a project that involves graphing text file data into a pyqt graph and I have been running into problems with a subclass QDialog box. My goal is to have the QDialog box use a combox to choose between different data sets to graph (The code below shows the "steering angle" setting being chosen). The problem lies with how to make it so that when the Create Graph button is pressed (Found in the QDialog Class), it runs the createGraph(self): function in the main class. I dont know how to work classes that well so I dont know how to make this work.
If anyone has any pointers on either how to get this working, how to properly structure a PYQT Program or how to make it more efficient, I'm all ears.
Thank you for your time!
Main Window Code:
class MainWidget(QMainWindow):
def __init__(self, parent=None):
super(MainWidget, self).__init__(parent)
self.activateWindow()
self.raise_()
self.setupGraph()
self.dockcheck = 0
self.graphcheck = 0
self.setWindowTitle("Drag and Drop Test")
self.resize(1200, 800)
self.setAcceptDrops(True)
self.LBLDragAndDrop = QLabel("Drag And Drop Files Here")
self.LBLDragAndDrop.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
if self.graphcheck == 0:
self.setCentralWidget(self.LBLDragAndDrop)
self.path3 = "C:\\Users\\steph\\OneDrive\\Documents\\SAA Wing\\Coding\\Can Bus Data Reading\\Temporary Saves"
self.treeview = QTreeView()
self.treeview.setAnimated(True)
self.fileModel = QFileSystemModel()
self.fileModel.setRootPath(self.path3)
self.indexRoot = self.fileModel.index(self.fileModel.rootPath())
self.treeview.setModel(self.fileModel)
self.treeview.setRootIndex(self.fileModel.index(self.path3))
self.treeview.setColumnWidth(0, 250)
self.treeview.doubleClicked.connect(self.onSelectionChanged)
#self.treeview.doubleClicked.connect(self.openDialog)
####################################################################################################################
# Dialog Box
####################################################################################################################
def onSelectionChanged(self, index):
self.selectionPath = self.sender().model().filePath(index)
self.selectionFilename = (self.selectionPath.split("/")[-1])
IDList = ("ID 00d0","ID 00d1","ID 00d3","ID 00d4","ID 0140","ID 0141","ID 0360","ID 0361")
if self.selectionFilename in IDList:
if self.selectionFilename == "ID 00d0":
editDialog = Dialog00d0()
editDialog.exec_()
####################################################################################################################
# Graphing data
####################################################################################################################
def createGraph(self):
self.graphcheck = 1
if self.graphcheck == 1:
self.setCentralWidget(self.scroll_area)
################################################################################################################
# ID 00D0 Creating Graph
################################################################################################################
if self.selectionFilename == "ID 00d0":
self.df00d0 = pd.read_table(self.selectionPath, header=None , delim_whitespace=True, dtype=object)
self.df00d0.columns = ['Timestamp','ID',"B0","B1","B2","B3","B4","B5","B6","B7"]
self.df00d0.dropna(inplace=True)
self.SA = np.array([], dtype=float)
self.LatAcc = np.array([], dtype=float)
self.LonAcc = np.array([], dtype=float)
self.ComAcc = np.array([], dtype=float)
self.Time00d0 = np.array([], dtype=float)
self.Timestamp00d0 = np.array([], dtype=float)
############################################################################################################
# Getting Time Stamps
############################################################################################################
for item in self.df00d0['Timestamp']:
self.Time00d0 = np.append(self.Time00d0, datetime.fromtimestamp(float(item)).strftime("%H:%M:%S.%f")[:-4])
self.Timestamp00d0 = np.append(self.Timestamp00d0, float(item))
############################################################################################################
# Steering Angle Graph
############################################################################################################
if self.combobox00d0.currentText() == "Steering Angle":
SA_ = (((self.df00d0['B1']) + (self.df00d0['B0'])).apply(int, base=16) * 0.1)
for item in SA_:
if item > 6000:
self.SA = np.append(self.SA, round((item - 6553.6), 1))
else:
self.SA = np.append(self.SA, round(item))
y_value = self.SA
Here is the QDialog Box class code:
class Dialog00d0(QDialog):
def __init__(self):
super().__init__()
self.layout = QVBoxLayout()
hlay = QHBoxLayout()
self.setLayout(self.layout)
self.setWindowTitle("Create Graph")
label = QLabel("Data Type")
self.combobox00d0 = QComboBox()
self.combobox00d0.addItem("Steering Angle")
self.combobox00d0.addItem("Latitudinal Acceleration")
self.combobox00d0.addItem("Longitudinal Acceleration")
self.combobox00d0.addItem("Combined Acceleration")
self.BTNCreateGraph = QPushButton("Create Graph")
self.BTNCancel = QPushButton("Cancel")
hlay.addWidget(self.BTNCreateGraph)
hlay.addWidget(self.BTNCancel)
self.layout.addWidget(label)
self.layout.addWidget(self.combobox00d0)
self.layout.addLayout(hlay)
self.BTNCreateGraph.clicked.connect("I need the self.creatGraph here")
self.BTNCancel.clicked.connect("self.close")
I imagine this will help you.
The pyqtSignal() argument tells you what information you want to carry.
In this case, I'm passing a text.
Good luck, I hope I helped.
import sys
from PyQt5.QtWidgets import QMainWindow, QDialog, QApplication
from PyQt5.QtWidgets import QPushButton, QVBoxLayout
from PyQt5 import QtCore, QtGui
class MainWidget(QMainWindow):
def __init__(self, parent=None):
super(MainWidget, self).__init__(parent)
button = QPushButton("Button to open dialog")
button.clicked.connect(self.button_clicked)
self.setCentralWidget(button)
self.show()
def button_clicked(self):
dlg = Dialog00d0()
dlg.signEmit.connect(self.createGraph)
dlg.exec()
def createGraph(self, _str):
print('Now Im here')
print(_str)
class Dialog00d0(QDialog):
signEmit = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
self.layout = QVBoxLayout()
self.BTNCreateGraph = QPushButton("link to createGraph()")
self.layout.addWidget(self.BTNCreateGraph)
self.setLayout(self.layout)
self.BTNCreateGraph.clicked.connect(self.BTNCreateGraph_clicked)
def BTNCreateGraph_clicked(self):
self.signEmit.emit('But I passed by')
app = QApplication(sys.argv)
win = MainWidget()
app.exec()
Problem Statement Below,
We have a large log file which stores user interactions with an application. The entries in the log file follow the following schema: {userId, timestamp, actionType} where actionType is one of two possible values: [open, close]
Constraints:
The log file is too big to fit in memory on one machine. Also assume that the aggregated data doesn’t fit into memory.
Code has to be able to run on a single machine.
Should not use an out-of-the box implementation of mapreduce or 3rd party database; don’t assume we have a Hadoop or Spark or other distributed computing framework.
There can be multiple entries of each actionType for each user, and there might be missing entries in the log file. So a user might be missing a close record between two open records or vice versa.
Timestamps will come in strictly ascending order.
For this problem, we need to implement a class/classes that computes the average time spent by each user between open and close. Keep in mind that there are missing entries for some users, so we will have to make a choice about how to handle these entries when making our calculations. Code should follow a consistent policy with regards to how we make that choice.
The desired output for the solution should be [{userId, timeSpent},….] for all the users in the log file.
Sample log file (comma-separated, text file)
1,1435456566,open
2,1435457643,open
3,1435458912,open
1,1435459567,close
4,1435460345,open
1,1435461234,open
2,1435462567,close
1,1435463456,open
3,1435464398,close
4,1435465122,close
1,1435466775,close
Approach
Below is the code I've written in Python & Scala, which seems to be not efficient and upto the expectations of the scenario given, I'd like to feedback from community of developers in this forum how better we could optimise this code as per given scenario.
Scala implementation
import java.io.FileInputStream
import java.util.{Scanner, Map, LinkedList}
import java.lang.Long
import scala.collection.mutable
object UserMetrics extends App {
if (args.length == 0) {
println("Please provide input data file name for processing")
}
val userMetrics = new UserMetrics()
userMetrics.readInputFile(args(0),if (args.length == 1) 600000 else args(1).toInt)
}
case class UserInfo(userId: Integer, prevTimeStamp: Long, prevStatus: String, timeSpent: Long, occurence: Integer)
class UserMetrics {
val usermap = mutable.Map[Integer, LinkedList[UserInfo]]()
def readInputFile(stArr:String, timeOut: Int) {
var inputStream: FileInputStream = null
var sc: Scanner = null
try {
inputStream = new FileInputStream(stArr);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
val line: String = sc.nextLine();
processInput(line, timeOut)
}
for ((key: Integer, userLs: LinkedList[UserInfo]) <- usermap) {
val userInfo:UserInfo = userLs.get(0)
val timespent = if (userInfo.occurence>0) userInfo.timeSpent/userInfo.occurence else 0
println("{" + key +","+timespent + "}")
}
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
}
def processInput(line: String, timeOut: Int) {
val strSp = line.split(",")
val userId: Integer = Integer.parseInt(strSp(0))
val curTimeStamp = Long.parseLong(strSp(1))
val status = strSp(2)
val uInfo: UserInfo = UserInfo(userId, curTimeStamp, status, 0, 0)
val emptyUserInfo: LinkedList[UserInfo] = new LinkedList[UserInfo]()
val lsUserInfo: LinkedList[UserInfo] = usermap.getOrElse(userId, emptyUserInfo)
if (lsUserInfo != null && lsUserInfo.size() > 0) {
val lastUserInfo: UserInfo = lsUserInfo.get(lsUserInfo.size() - 1)
val prevTimeStamp: Long = lastUserInfo.prevTimeStamp
val prevStatus: String = lastUserInfo.prevStatus
if (prevStatus.equals("open")) {
if (status.equals(lastUserInfo.prevStatus)) {
val timeSelector = if ((curTimeStamp - prevTimeStamp) > timeOut) timeOut else curTimeStamp - prevTimeStamp
val timeDiff = lastUserInfo.timeSpent + timeSelector
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, timeDiff, lastUserInfo.occurence + 1))
} else if(!status.equals(lastUserInfo.prevStatus)){
val timeDiff = lastUserInfo.timeSpent + curTimeStamp - prevTimeStamp
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, timeDiff, lastUserInfo.occurence + 1))
}
} else if(prevStatus.equals("close")) {
if (status.equals(lastUserInfo.prevStatus)) {
lsUserInfo.remove()
val timeSelector = if ((curTimeStamp - prevTimeStamp) > timeOut) timeOut else curTimeStamp - prevTimeStamp
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, lastUserInfo.timeSpent + timeSelector, lastUserInfo.occurence+1))
}else if(!status.equals(lastUserInfo.prevStatus))
{
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, lastUserInfo.timeSpent, lastUserInfo.occurence))
}
}
}else if(lsUserInfo.size()==0){
lsUserInfo.add(uInfo)
}
usermap.put(userId, lsUserInfo)
}
}
Python Implementation
import sys
def fileBlockStream(fp, number_of_blocks, block):
#A generator that splits a file into blocks and iterates over the lines of one of the blocks.
assert 0 <= block and block < number_of_blocks #Assertions to validate number of blocks given
assert 0 < number_of_blocks
fp.seek(0,2) #seek to end of file to compute block size
file_size = fp.tell()
ini = file_size * block / number_of_blocks #compute start & end point of file block
end = file_size * (1 + block) / number_of_blocks
if ini <= 0:
fp.seek(0)
else:
fp.seek(ini-1)
fp.readline()
while fp.tell() < end:
yield fp.readline() #iterate over lines of the particular chunk or block
def computeResultDS(chunk,avgTimeSpentDict,defaultTimeOut):
countPos,totTmPos,openTmPos,closeTmPos,nextEventPos = 0,1,2,3,4
for rows in chunk.splitlines():
if len(rows.split(",")) != 3:
continue
userKeyID = rows.split(",")[0]
try:
curTimeStamp = int(rows.split(",")[1])
except ValueError:
print("Invalid Timestamp for ID:" + str(userKeyID))
continue
curEvent = rows.split(",")[2]
if userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==1 and curEvent == "close":
#Check if already existing userID with expected Close event 0 - Open; 1 - Close
#Array value within dictionary stores [No. of pair events, total time spent (Close tm-Open tm), Last Open Tm, Last Close Tm, Next expected Event]
curTotalTime = curTimeStamp - avgTimeSpentDict[userKeyID][openTmPos]
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
avgTimeSpentDict[userKeyID][totTmPos] = totalTime
avgTimeSpentDict[userKeyID][closeTmPos] = curTimeStamp
avgTimeSpentDict[userKeyID][nextEventPos] = 0 #Change next expected event to Open
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==0 and curEvent == "open":
avgTimeSpentDict[userKeyID][openTmPos] = curTimeStamp
avgTimeSpentDict[userKeyID][nextEventPos] = 1 #Change next expected event to Close
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==1 and curEvent == "open":
curTotalTime,closeTime = missingHandler(defaultTimeOut,avgTimeSpentDict[userKeyID][openTmPos],curTimeStamp)
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
avgTimeSpentDict[userKeyID][totTmPos]=totalTime
avgTimeSpentDict[userKeyID][closeTmPos]=closeTime
avgTimeSpentDict[userKeyID][openTmPos]=curTimeStamp
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==0 and curEvent == "close":
curTotalTime,openTime = missingHandler(defaultTimeOut,avgTimeSpentDict[userKeyID][closeTmPos],curTimeStamp)
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
avgTimeSpentDict[userKeyID][totTmPos]=totalTime
avgTimeSpentDict[userKeyID][openTmPos]=openTime
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
elif curEvent == "open":
#Initialize userid with Open event
avgTimeSpentDict[userKeyID] = [0,0,curTimeStamp,0,1]
elif curEvent == "close":
#Initialize userid with missing handler function since there is no Open event for this User
totaltime,OpenTime = missingHandler(defaultTimeOut,0,curTimeStamp)
avgTimeSpentDict[userKeyID] = [1,totaltime,OpenTime,curTimeStamp,0]
def missingHandler(defaultTimeOut,curTimeVal,lastTimeVal):
if lastTimeVal - curTimeVal > defaultTimeOut:
return defaultTimeOut,curTimeVal
else:
return lastTimeVal - curTimeVal,curTimeVal
def computeAvg(avgTimeSpentDict,defaultTimeOut):
resDict = {}
for k,v in avgTimeSpentDict.iteritems():
if v[0] == 0:
resDict[k] = 0
else:
resDict[k] = v[1]/v[0]
return resDict
if __name__ == "__main__":
avgTimeSpentDict = {}
if len(sys.argv) < 2:
print("Please provide input data file name for processing")
sys.exit(1)
fileObj = open(sys.argv[1])
number_of_chunks = 4 if len(sys.argv) < 3 else int(sys.argv[2])
defaultTimeOut = 60000 if len(sys.argv) < 4 else int(sys.argv[3])
for chunk_number in range(number_of_chunks):
for chunk in fileBlockStream(fileObj, number_of_chunks, chunk_number):
computeResultDS(chunk, avgTimeSpentDict, defaultTimeOut)
print (computeAvg(avgTimeSpentDict,defaultTimeOut))
avgTimeSpentDict.clear() #Nullify dictionary
fileObj.close #Close the file object
Both program above gives desired output, but efficiency is what matters for this particular scenario. Let me know if you've anything better or any suggestions on existing implementation.
Thanks in Advance!!
What you are after is iterator usage. I'm not going to re-write your code, but the trick here is likely to be using an iterator. Fortunately Scala provides decent out of the box tooling for the job.
import scala.io.Source
object ReadBigFiles {
def read(fileName: String): Unit = {
val lines: Iterator[String] = Source.fromFile(fileName).getLines
// now you get iterator semantics for the file line traversal
// that means you can only go through the lines once, but you don't incur a penalty on heap usage
}
}
For your use case, you seem to require a lastUser, so you're dealing with groups of 2 entries. I think you you have two choices, either go for iterator.sliding(2), which will produce iterators for every pair, or simply add recursion to the mix using options.
def navigate(source: Iterator[String], last: Option[User]): ResultType = {
if (source.hasNext) {
val current = source.next()
last match {
case Some(existing) => // compare with previous user etc
case None => navigate(source, Some(current))
}
} else {
// exit recursion, return result
}
}
You can avoid all the code you've written to read the file and so on. If you need to count occurrences, simply build a Map inside your recursion, and increment the occurrences at every step based on your business logic.
from queue import LifoQueue, Queue
def averageTime() -> float:
logs = {}
records = Queue()
with open("log.txt") as fp:
lines = fp.readlines()
for line in lines:
if line[0] not in logs:
logs[line[0]] = LifoQueue()
logs[line[0]].put((line[1], line[2]))
else:
logs[line[0]].put((line[1], line[2]))
for k in logs:
somme = 0
count = 0
while not logs[k].empty():
l = logs[k].get()
somme = (somme + l[0]) if l[1] == "open" else (somme - l[0])
count = count + 1
records.put([k, somme, count//2])
while not records.empty():
record = records.get()
print(f"UserId={record[0]} Avg={record[1]/record[2]}")
I am subscript to a message feed for a number of fields, I need to set the values from the feed to the domain object and have code like below:
if (map.contains(quoteBidPriceAcronym)) {
quote.bid.price = Some(map.get(quoteBidPriceAcronym).get.asInstanceOf[Number].doubleValue());
quote.changed = true;
}
if (map.contains(quoteBidSizeAcronym)) {
quote.bid.size = Some(sizeMultipler() * map.get(quoteBidSizeAcronym).get.asInstanceOf[Number].intValue());
quote.changed = true;
}
if (map.contains(quoteBidNumAcronym)) {
quote.bid.num = Some(map.get(quoteBidNumAcronym).get.asInstanceOf[Number].shortValue());
quote.changed = true;
}
if (map.contains(quoteAskPriceAcronym)) {
quote.ask.price = Some(map.get(quoteAskPriceAcronym).get.asInstanceOf[Number].doubleValue());
quote.changed = true;
}
if (map.contains(quoteAskSizeAcronym)) {
quote.ask.size = Some(sizeMultipler() * map.get(quoteAskSizeAcronym).get.asInstanceOf[Number].intValue());
quote.changed = true;
}
if (map.contains(quoteAskNumAcronym)) {
quote.ask.num = Some(map.get(quoteAskNumAcronym).get.asInstanceOf[Number].shortValue());
quote.changed = true;
}
if (map.contains(quoteExchTimeAcronym)) {
quote.exchtime = getExchTime(String.valueOf(map.get(quoteExchTimeAcronym).get));
}
It look pretty redundant, any suggestion to improve it?
You can do something like:
map.get(quoteBidPriceAcronym).map { item =>
quote.bid.price = item.map(_.asInstanceOf[Number].doubleValue())
quote.changed = true
}
Other issues might be better to fix outside. E.g. why map[quoteBidPriceAcronym] is storing an Option, if your code assumes it's not going to be None?
Something like this perhaps?
val handlers = Map[String, Number => Unit] (
quoteBidPriceAcronym -> { n => quote.bid.price = Some(n.doubleValue) },
quoteBidSizeAcronym -> { n => quote.bid.size = Some(sizeMultipler() * n.intValue },
etc. ...
)
for {
(k,handler) <- handlers
values <- map.get(k).toSeq
quote.chanded = true
_ = handler(n.asInstanceof[Number])
}
Personally, I don't like code changing an object state (quote) but this is a question on Scala, not functional programming.
That said I would reverse the way you are using you map map keys. Instead of checking whether a value exists to perform some action, I'd have a map from your keys to actions and I'd iterate over your map elements.
e.g (assuming map is of the type Map[String, Any]):
val actions: Map[String, PartialFunction[Any, Unit]] = Map(
(quoteBidPriceAcronym, {case n: Number => quote.bid.price = Some(n.doubleValue())}),
(quoteBidSizeAcronym, {case n: Number => quote.bid.size = Some(sizeMultipler() * n.doubleValue())}),
...
...
)
for((k,v) <- map; action <- actions.get(k); _ <- action.lift(v))
quote.changed = true;
The for construct here iterates over map key-values, then (next level of iteration, over the possible action available for the key. If an action is found, which is a partial function, it gets lifted to make it a function from Any to Option[Unit]. That way, you can iterate in an additional inner level so quote.changed = true is only run when the action is defined for v.
I have a special class Model that needs to have its methods called in a very specific order.
I tried doing something like this:
val model = new Model
new MyWrappingClass {
val first = model.firstMethod()
val second = model.secondMethod()
val third = model.thirdMethod()
}
The methods should be called in the order listed, however I am seeing an apparently random order.
Is there any way to get the variable initialization methods to be called in a particular order?
I doubt your methods are called in the wrong order. But to be sure, you can try something like this:
val (first, second, third) = (
model.firstMethod(),
model.secondMethod(),
model.thirdMethod()
)
You likely have some other problem with your code.
I can run 100 million loops where it never gets the order wrong, as follows:
class Model {
var done = Array(false,false,false);
def firstMethod():Boolean = { done(0) = true; done(1) || done(2) };
def secondMethod():Boolean = { done(1) = true; !done(0) || done(2) };
def thirdMethod():Boolean = { done(2) = true; !done(0) || !done(1) };
};
Notice that these methods return a True if done out of order and false when called in order.
Here's your class:
class MyWrappingClass {
val model = new Model;
val first = model.firstMethod()
val second = model.secondMethod()
val third = model.thirdMethod()
};
Our function to check for bad behavior on each trial:
def isNaughty(w: MyWrappingClass):Boolean = { w.first || w.second || w.third };
A short program to test:
var i = 0
var b = false;
while( (i<100000000) && !b ){
b = isNaughty(new MyWrappingClass);
i += 1;
}
if (b){
println("out-of-order behavior occurred");
println(i);
} else {
println("looks good");
}
Scala 2.11.7 on OpenJDK8 / Ubuntu 15.04
Of course this doesn't prove it impossible to have wrong order, only that correct behavior seems highly repeatable in a fairly simple case.
How does this Emacs command (make-comint-in-buffer "Python" nil "python" nil "-i") or (make-comint-in-buffer "git" nil "C:/Program Files (x86)/Git/bin/sh.exe" nil "--login" "-i") manage to get the prompt in an Emacs buffer and get ride of it's, Python's/sh.exe's, interactive terminal without killing the Python process?
I tried to figure out by taking a shallow dive into make-comint-in-buffer's source code but bumped into processp, which is C compiled code, whose source I couldn't find.
The reason I am asking this question is to find an alternative answer to this question without using pythonw (their aint a mayapyw.exe to mayapy.exe for example).
Emacs uses the SHOWWINDOW flag to CreateProcess to control display of the console window associated with a subprocess.
The key code from create_child in w32proc.c is:
if (NILP (Vw32_start_process_show_window) && !is_gui_app)
start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
else
start.dwFlags = STARTF_USESTDHANDLES;
start.wShowWindow = SW_HIDE;
if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE, flags, env, dir, &start, &cp->procinfo))
{ ...
}
I can only guess how that Emacs command works, so can't really help you there... But however, I can provide you with a way to hide a window. That is possible by using the CTypes module and call the Windows-API to get the Window/Python-prompts ID/Hwin, and then hide that window.
This forces you to import/or include this piece of code in your script, and then call a function/do a little something in your script. Once your script is run, this should hide the prompt. See "main.py"-part for usage.
Window.py
from ctypes import *
user32 = windll.user32
BOOL = c_bool
INT = c_int
LONG = c_long
LPVOID = c_void_p
LPTSTR = c_wchar_p
HWND = LPVOID
LPARAM = LPVOID
GW_OWNER = 4
GWL_EXSTYLE = -20
WS_EX_TOOLWINDOW = 128
WS_EX_APPWINDOW = 262144
#------------------------------------------------------------------------
def GetWindowLong(hwnd, index):
user32.GetWindowLongW.argtypes = [HWND, INT]
return user32.GetWindowLongW(hwnd, index)
def GetWindow(hWnd, uCmd):
user32.GetParent.argtypes = [HWND, INT]
return user32.GetWindow(hWnd, uCmd)
def GetParent(hwnd):
user32.GetParent.argtypes = [HWND]
return user32.GetParent(hwnd)
def IsWindowVisible(hwnd):
user32.IsWindowVisible.argtypes = [HWND]
return user32.IsWindowVisible(hwnd)
def GetWindowTextLength(hwnd):
user32.GetWindowTextLengthW.argtypes = [HWND]
return user32.GetWindowTextLengthW(hwnd)
def GetWindowText(hwnd):
length = GetWindowTextLength(hwnd)
if not length: return False
buff = create_unicode_buffer(length + 1)
user32.GetWindowTextW.argtypes = [HWND, LPTSTR, INT]
res = user32.GetWindowTextW(hwnd, buff, length + 1)
if res: return buff.value
else: return False
def isRealWindow(hwnd):
""" Check if a given window is a real Windows application frame..
Returns a BOOL """
if not IsWindowVisible(hwnd):
return False
if GetParent(hwnd) != 0:
return False
hasNoOwner = GetWindow(hwnd, GW_OWNER) == 0
lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
if (((lExStyle & WS_EX_TOOLWINDOW) == 0 and hasNoOwner)
or ((lExStyle & WS_EX_APPWINDOW != 0) and not hasNoOwner)):
if GetWindowText(hwnd):
return True
return False
class WindowEnumerator(object):
""" Window enumerator class. You can pass it's instances
as callback functions in window enumeration APIs. """
def __init__(self):
self.hwnd = []
def __call__(self, hwnd, lParam):
self.hwnd.append(hwnd)
return True
class __EnumWndProc(WindowEnumerator):
pass
def EnumWindows():
WNDENUMPROC = WINFUNCTYPE(BOOL,HWND,LPARAM)
_EnumWindows = user32.EnumWindows
_EnumWindows.argtypes = [WNDENUMPROC, LPARAM]
_EnumWindows.restype = BOOL
EnumFunc = __EnumWndProc()
lpEnumFunc = WNDENUMPROC(EnumFunc)
if not _EnumWindows(lpEnumFunc, None):
errcode = GetLastError()
if errcode not in (ERROR_NO_MORE_FILES, ERROR_SUCCESS):
raise WinError(errcode)
return EnumFunc.hwnd
def GetWindowByName(title):
window = []
hwnds = EnumWindows()
for hwnd in hwnds:
if not isRealWindow(hwnd):
pass
else:
wndtitle = GetWindowText(hwnd)
if title.lower() in wndtitle.lower():
return (hwnd, wndtitle)
return False
def ShowWindow(hWnd, arg=0):
user32.ShowWindow.argtypes = [HWND, c_int]
return user32.ShowWindow(hWnd, arg)
main.py
import Window
# Pass the full or partial title of the window that should be hidden.
wnd = Window.GetWindowByName('xxxxxxx.exe')
if wnd:
Window.ShowWindow(wnd[0], 0) #Hide it. 0=SW_HIDE, 5 = SW_SHOW.
I hope this does the trick.