Shiny, RStudio - how to remove objects created by eventReactive functions - rstudio

I'm in Shiny, RStudio. I'm making an app that processes a user input in several steps, each step taking input from the previous step. At each step the user can set several parameters to process the input.
The workflow looks like this:
Step1: upload input from user
obj_step1 <- eventReactive(input$actionButton1, {#function to upload input from user})
output$step1 <- renderPlot({#function to display obj_step1})
Step2:
obj_step2 <- eventReactive(input$actionbutton2, {#function to process obj_step1, taking several user given parameters from the ui with input$})
output$step2 <- renderPlot({#function to display obj_step3})
Step3:
obj_step3 <- eventReactive(input$actionbutton3, {#function to process obj_step2, taking several user given parameters from the ui with input$})
output$step3 <- renderPlot({#function to display obj_step3})
Step4:
obj_step4 <- eventReactive(input$actionbutton4, {#function to process obj_step3, taking several user given parameters from the ui with input$})
output$step4 <- renderPlot({#function to display obj_step4})
My problem: the user has gone through all the steps and concludes that, to get the best results, he needs to restart the process from step 2, with new parameters. How do I remove all the objects and outputs from the step3-4, to ensure that no mix up takes place?
I've tried remove(obj_step4()), but it does not support this type of objects.

After some days running around in circles, I found the reactiveValues() function from shiny (http://shiny.rstudio.com/articles/). It helps to empty the objects from eventReactive functions when an actionButton of a previous step is pressed. For more details follow the link to the manual pages.

Related

SAP Script Recording and Playback - Cumulative data

If I am using the Script Recording and Playback feature on same transaction for instance ME25, multiple times, I am getting cumulative data as part of multiple scripts rather than incremental data.
Explanation :
If I open ME25 details and enter "100-310" as Material and "Ball Bearing" as Short Text and stop the recording, I get the following script, which is expected behavior.
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-MATNR[3,0]").text = "100-310"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").text = "Ball Bearing"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").setFocus
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").caretPosition = 12
After this, I restart the recording and type Qty Requested as "100" and delivery date as "21.04.2021" and stop the recording. I get the following script:
session.findById("wnd[0]").maximize
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-MATNR[3,0]").text = "100-310"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").text = "Ball Bearing"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-MENGE[5,0]").text = "100"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtRM06B-EEIND[8,0]").text = "21.04.2021"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-EKGRP[9,0]").setFocus
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-EKGRP[9,0]").caretPosition = 0
Instead of getting the incremental part that I typed for the second recording instance, I am getting complete script. Is there a way to achieve incremental scripts?
I can reproduce in my SAP GUI 7.60 (whatever screen it is; whatever kind of field it is, I can reproduce even with very simple fields like in a Selection Screen).
It seems that it happens all the time, even if you write your own recorder (a VBS script which mainly uses session.record = True + event handlers). It's due to the fact that SAP GUI sends all the screen events (i.e. the user actions) since the screen was entered, when the user presses a button, a function key, closes a window, or stops the SAP GUI Recorder.
If you write your own recorder, I guess you can save the screen contents when you start the recorder, and when the "change" events occur you may ignore those ones where the new field value has not changed since the recorder started. But that's a lot of work.
I think that it's far more easy to append manually the last lines of the last script to the initial script.

Spring Batch - Is it possible to write a custom restart in spring batch

I have been writing a spring batch wherein I have to perform some error-handling.
I know that spring batch has its own way of handling errors and restarts.
However, when the batch fails and restarts again, I want to pass my own values, conditions and parameters (for restart) which need to be followed before starting/executing the first step.
So, is it possible to write such custom restart in spring batch?
UPDATE1:(Providing a better explanation for above question.)
Let's say that the input to my reader in Step 1 is in the following format:
Table with following columns:
CompanyName1 -> VehicleId1
CN1 -> VID2
CN1 -> VID3
.
.
CN1 -> VID30
CN2 -> VID1
CN2 -> VID2
.
.
CNn -> VIDn
The reader reads this table row by row for a chunk size 1 (so in this case the row retrieved will be CN -> VID ) processes it and writes it to a File object.
This process goes on until all the CN1 type data is written into the File object. When the reader sends the row with company Name of type CN2 , the File object that was created earlier (for company name of type CN1) will be stored in a remote location. Then the process of File Object creation will continue for CN2 until we encounter CN3, in which case CN2 File Object will be sent for storage to a remote location
and the process will continue.
Now, once you understand this, here's a catch.
Let's say the data is currently being written by the writer for company Name 2 (CN2) and vehicle ID is VID20 (CN2 -> VID20)
in the File object. Then, due to some reason we had to stop the job/the job fails. In that case, the instance that will be saved will be CN2 -> VID20. So, next time when the job runs, it will start from CN2->VID20
As you might have guessed, all the 19 entries before CN2->VID20 which were written in the File Object were deleted permanently when the file Object got destroyed and these entries were never sent through the File to remote location.
So my question here is this:
Is there a way where I can write my custom restart for the batch where I could tell the job to start from CN2->VID1 instead of CN2->VID20?
If you could think of any other way to handle this scenario then such suggestions are also welcome.
Since you want to write the data of each company in a separate file, I would use the company name as a job parameter. With this approach:
Each job will read the data of a single company and write it to a file
If a job fails, you can restart it and it would resume where it left off (Spring Batch will truncate the file to last known written offset before writing new data). So there is no need for a custom restart "policy".
No need to set the chunk-size to 1, this is not efficient. You can use a reasonable chunk size with this approach
If the number of companies is small enough, you can run jobs manually. Otherwise, you can always get the distinct values with something like select distinct(company_name) from yourTable and write a script/loop to launch batch jobs with different parameters. Bottom line, make each job do one thing and do it well.

Drupal 7 ignoring $_SESSION in template

I'm working on a simple script in a custom theme in Drupal 7 that is supposed to just rotate through different background image each time a user loads the page. This is my code in [view].tpl.php that picks which image to use.
$img_index = (!isset($_SESSION["img_index"]) || is_null($_SESSION["img_index"])) ? 1 : $_SESSION["img_index"] + 1;
if ($img_index > 2) {
$img_index = 0;
}
$_SESSION["img_index"] = $img_index;
Pretty simple stuff, and it works fine as long as Drupal starts up a session. However, if I delete my session cookie, then always shows the same image, a session is never started.
I'm assuming that since this code is in the view file that the view code is being cached for anonymous users and hence the session is never started, but I can't figure out how to otherwise do what I want.
Don't mess with session like /u/maiznieks mentioned on Reddit. It's going to affect performance.
I've had to do something similar in the past and went with an approach like /u/maiznieks mentions. It's something like this,
Return all the URLs in an array via JS on Drupal.settings.
Check if a cookie is set.
If it's not, set it and set it's value to 0.
If it's set, get the value, increase the value by one, save it to the cookie.
With that value, now you have an index.
Check if image[index] exists
If it does, show that to the user.
If it doesn't, reset index to 0 and show that. Save 0 to the cookie.
You keep caching. You keep showing the user new images on every page load.
You could set your current view to do a random sort every 5 mins. You would then only have to update the logic above to replace that image. That way you can keep something similar working for users with no JS but still keep this functionality for the rest.
You can replace cookies above with HTML5 local storage if you'd like.
#hobberwickey, I will suggest to create a custom module and implement hook_boot() in module. As per drupal bootstrap process session layer will call after cache layer everytime. hook_boot can be called in cache pages and before bootstrap process also. You can take more information here.

onTestComplete function

Basically the first script runs correctly on the Web (Action 1) . This inputted information is transferred from the web to a terminal emulator (backend non QTP related). → Done
A second action is then used on the terminal emulator to complete/test information.
So in effect, there are two scripts:
Action 1 for the web,
Action 2 for the emulator
The script for the terminal emulator also runs fine.
So the problem is this:
I don't want to call the Action 2 until Action 1 is complete (simple I arrange the actions in order they are to fire). → Done
However, I want the Action 2 to run off the datasheet from Action 1. I don't want to have to copy all the information manually from Action 1 to Action 2. Usually this is simple, as I can use the setRow(), getRow() methods. But the Action 2 datasheet is blank (as Action 1 has all the data). I can't run the Action 2, because there are no literation to run (again the datasheet in Action 2 is blank). QTP just reverts back to Action 1, because it thinks as there are now entries on Action 2, then Action 2 is complete.
All I want to do is associate Action 2 directly with the datasheet in Action 1. I don't want to simply extend the code to Action 1, because users will be moving consistently between Action 1 and Action 2.
So in a nut shell, is there
a code to copy all datasheet contents from Action 1 to Action 2 (but do this only once, not on every iteration) so that Action two can run on what ever row I choose from?
a simple way to associate the code of Action 2 to the Datasheet data of Action 1?
a way to use a library function file rather than action to run the datasheet information associated with Action 1?
Consider using Datatable.ImportSheet and programmatically import your test data.
Please note that, you will have to change your current row for every iteration. It should be on the start of your test... Something like
If DataTable.GetRowCount > DataTable.GetCurrentRow Then
DataTable.SetCurrentRow = DataTable.GetCurrentRow + 1
End If
I used similar to the above. Using the datatable.getCurrentRow method allowed me to access the correct row on the second spreadsheet

Visual Basic: How to use timer properly

I'm trying to write a simple program that could perform some tasks at specified time.
Here's what I have:
If (TimeOfDay = "06:12:50") Then
MsgBox(TimeOfDay)
End If
If (TimeOfDay = "06:13:58") Then
MsgBox(TimeOfDay)
End If
This code is placed inside Timer1_Tick, I set time interval - 1000 and it works OK, I get TimeOfDay value in MsgBox when current time is equal to my specified time.
But what should I do to make it work dynamically? For example: I want to type TIME value via TextBox and pass it to Timer1_Tick I need to do it as many times as I want so everytime current time matches with my specified hour,minute,second it would work, but I don't know where I have to put my code, because if I place code in while loop and in Time_Ticker1 it runs while loop every second and UI crashes immediately.
Thank you in advance for your help!
Have you considered setting a Windows Scheduled event of MSG to yourself using the AT command line? The operating system timer/scheduler, dialog, storage and queue are already there and the MSG can optionally be dismissed if there is no one to receive it within a set amount of time. Example to send the time at 06:12:15 run the following into a command shell.
AT 06:12:15 msg %USERNAME% It is 06:12:15 am

Resources