This is my first post on here. Thank you in advance for taking the time to read my question.
I am a novice coder. I have a minor in Computer Science that I got a decade ago. I had an urge to do some simple coding, and an opportunity came up, so I did!
In developing a game, I wanted to run a program to determine the chances of given outcomes with given parameters. I excitedly reached the point where it was a go, but Google Scripts couldn't handle running the 60,000,000 possible scenarios in order to compute a win%.
I got, "error: Exceeded maximum execution time."
I'm just trying to find the shortest path between me and running this program. Ideas:
1) Is there a way to remove the maximum execution time and let it just take all day? Is there some other way I can get it to run in Google Scripts?
2) Perhaps I can run a smaller number of trials by inputing random numbers. Is there a way to generate random numbers in Google Scripts?
3) Should I be doing this kind of thing in something besides Google Scripts? If so, is there a free/affordable compiler for Mac I should look into? I tried importing it into Xcode, but I'm bewildered and can't seem to get to a simple place to compile. Also, importing it to "C" is creating some compatibility issues; though I may just have to suck it up and retool it here.
For reference, here's the function that's timing it out:
function dieFeeder(winCount, fSkill, fMagnitude, fHeart, fDie1, fDie2, fDie3, fDie4, fDie5, cSkill, cMagnitude, cHeart, cDie1, cDie2, cDie3, cDie4, cDie5){
// a parent function to function questionMatrix, feeds the changing dice into it
var matrixWinner;
//This 'for' clause keeps going until all dice permutations have been tried out
for (var i=0; i<60466176; i++){
//This part changes the dice to go through all combiations in a way similar to counting in base 6
if (cDie5 == 7){
cDie5 = 1;
cDie4 = cDie4+1;
}
if (cDie4 == 7){
cDie4 = 1;
cDie3 = cDie3 +1;
}
if (cDie3 == 7){
cDie3 = 1;
cDie2 = cDie2 +1;
}
if (cDie2 == 7){
cDie2 = 1;
cDie1 = cDie1 +1;
}
if (cDie1 == 7){
cDie1 = 1;
fDie5 = fDie5 +1;
}
if (fDie5 == 7){
fDie5 = 1;
fDie4 = fDie4 +1;
}
if (fDie4 == 7){
fDie4 = 1;
fDie3 = fDie3 +1;
}
if (fDie3 == 7){
fDie3 = 1;
fDie2 = fDie2 +1;
}
if (fDie2 == 7){
fDie2 = 1;
fDie1 = fDie1 +1;
}
cDie5 = cDie5 + 1;
//This part checks to see who wins and increases the winCount if it was the Favorite
matrixWinner = questionMatrix(fSkill, fMagnitude, fHeart, fDie1, fDie2, fDie3, fDie4, fDie5, cSkill, cMagnitude, cHeart, cDie1, cDie2, cDie3, cDie4, cDie5);
if (matrixWinner == 'favorite'){
winCount = winCount +1;
}
}
return winCount;
}
There is no way to lift the maximum execution time. The limit is there so that other users (like me) can have time to run our scripts too! The solution to this problem is to break up your problem into many subproblems.
One solution would be to continue executing your script while your running time is under some threshold (say, 3 minutes) (i.e. keep track of how long your script has been running). Then save all state relating to your script (variables, etc.). Save these to ScriptDb. Then have your script run on a 5-minute trigger. When your script runs again, it reads the values from ScriptDb and picks up where it left off.
If you're looking for random numbers, use Math.random(). Google Apps Scripts is built off of javascript, so basic javascript functions are available.
Relating to my answer to #2, what you have shown is entirely javascript, so you can just copy your code over to some webpage to run it. (For testing, you can use jsfiddle).
Also you need to define if (cDie5 == 7){
Related
I'm trying to write a userscript for a friend. The Website I'm writing it for (app.patientaccess.com) tells you what doctors appointments you have, (among other things). However, in order to write my userscript, I need to know how the app handle appointments for the following year.
At the moment, the only way to know is to wait until the end of the year when my friend starts making appointments for the following year. Since it's an Angular app, I'd rather, if possible, point it to a fabricated JSON file of my creation when the app requests that particular data. In that file I can give it some data for this year and next year and then I can see what happens with appointments made for the following year.
I'm hoping this can be done with an addon for Chrome or Firefox or perhaps some kind of free/open source software.
Thanks in advance.
I came up with a function that will accurately guess there year, given the day name, date and month, if it's within a couple of years either side of the current year.
function calculateYear(dayName, dayOfMonth, monthNum, returnDateObj) {
monthNum -= 1;
maxIterations = 3;
var startYear = (new Date()).getFullYear();
var dateObj = new Date(startYear, monthNum, dayOfMonth);
for (var i = 0; i < maxIterations; i++) {
dateObj.setYear(startYear + (1 * i));
if (dayName == daysOfTheWeek[dateObj.getDay()]) {
return (returnDateObj) ? dateObj : dateObj.getFullYear();
}
dateObj.setYear(startYear - (i + 1));
if (dayName == daysOfTheWeek[dateObj.getDay()]) {
return (returnDateObj) ? dateObj : dateObj.getFullYear();
}
}
return 'No Match';
}
It works a treat, as you can see here.
I trying to find a way to snooze e-mail in my Gmail. Yes, I had Mailbox.app on my iDevice, but I want a way to Snooze or "Laterize" some emails.
I found a Blog Spot post and a Lifehacker one. The Lifehacker article just adds more pictures to the Blog Sport one. I followed the Lifehacker instructions. I made only one deviation from the code. In the two instances that the code says "7", I replaced it with "200".
The code I have is:
var MARK_UNREAD = false;
var ADD_UNSNOOZED_LABEL = false;
function getLabelName(i) {
return "Snooze/Snooze " + i + " days";
}
function setup() {
// Create the labels we’ll need for snoozing
GmailApp.createLabel("Snooze");
for (var i = 1; i <= 200; ++i) {
GmailApp.createLabel(getLabelName(i));
}
if (ADD_UNSNOOZED_LABEL) {
GmailApp.createLabel("Unsnoozed");
}
}
function moveSnoozes() {
var oldLabel, newLabel, page;
for (var i = 1; i <= 200; ++i) {
newLabel = oldLabel;
oldLabel = GmailApp.getUserLabelByName(getLabelName(i));
page = null;
// Get threads in "pages" of 100 at a time
while(!page || page.length == 100) {
page = oldLabel.getThreads(0, 100);
if (page.length > 0) {
if (newLabel) {
// Move the threads into "today’s" label
newLabel.addToThreads(page);
} else {
// Unless it’s time to unsnooze it
GmailApp.moveThreadsToInbox(page);
if (MARK_UNREAD) {
GmailApp.markThreadsUnread(page);
}
if (ADD_UNSNOOZED_LABEL) {
GmailApp.getUserLabelByName("Unsnoozed")
.addToThreads(page);
}
}
// Move the threads out of "yesterday’s" label
oldLabel.removeFromThreads(page);
}
}
}
}
But I'm getting an error:
Your script, Gmail Snooze, has recently failed to finish
successfully. A summary of the failure(s) is shown below.
Details:
Start: 9/10/13 12:16 AM
Function: moveSnoozes
Error Message: Service invoked too many times in a short time: gmail rateMax. Try Utilities.sleep(1000) between calls. (line 24, file "Code")
Trigger: time-based
End: 9/10/13 12:22 AM
Does anybody know how I can make use of Utilities.sleep(1000)? Where do I type that in?
The error you got is because creating 200 labels at the speed-of-code is too fast for Gmail and considered abuse of it's API. SO, as the error message suggests, you could use Utilities.sleep(1000) to wait a second between each label creation.
I'm not familiar with the script (Boomerang works well for me), but you might try making your 30, 60, 90 180 day labels by hand and letting the script pick up on them. Then you don't need to worry about the label creation at all.
In an effort to help you better understand the code you are reading. Below is an explanation of what's going on and how to insert the Utilities.sleep(). You will need to decide for how long you want to wait 1000ms means that you're waiting for 200 seconds, and if you have 3 min to spare that will do just fine. You could experiment to see at what point the Gmail app says 'Woah that's enough there. Take it slower please.'
NOTE: I am not attempting to re-engineer this to allow for a better creation/management of labels. There are a probably a number of enhancements that can be made to the code, and although tempting, they will be left as an exercise for the reader.
RE your pastie:
function setup() {
// This creates 1 label called "Snooze"
// it probably isn't causing the problem
GmailApp.createLabel("Snooze");
// This piece is a loop that will execute 200 times.
// It will do so as fast as GAS will let it.
// This is probably where the problem is...
for (var i = 1; i <= 200; ++i) {
// Create the label
GmailApp.createLabel(getLabelName(i));
// We should wait a bit before making the next one
// Utilities.sleep() will do well to go here
Utilities.sleep(/*Milliseconds to wait*/);
}
// I doubt this is causing the problem either.
// It's only one label creation
if (ADD_UNSNOOZED_LABEL) {
GmailApp.createLabel("Unsnoozed");
}
}
I have a list of cases in the queue that I need to grab. As you can imagine, it's a bit repetitive and time consuming. I'm new at programming and haven't figured a way to create a script that auto-click/grab these cases. Can someone help?
Code to:
1) Search and Click "Grab"
- will take 4 seconds for the page to refresh
2) Click grab again
3) stop after 50 cases are grabbed
This code doesn't work
window.setTimeout("pushSubmit()",3000);
function pushSubmit()
{document.getElementById('Grab').click();
Assuming your page is not refreshed in the process, you could keep a counter of how many "Grabs" you have done:
var counter = 0;
var maxCount = 50;
function pushSubmit() {
if(counter++ < maxCount) {
document.getElementById('Grab').click();
window.setTimeout(pushSubmit,3000);
}
}
//start the process
pushSubmit();
Here is a jsfiddle example
EDIT:
Or what I would probably prefer, set up the function so it can be used with any number of iterations.
function pushSubmit(max, count) {
count = typeof count !== 'undefined' ? count : 1;
if(count <= max) {
document.getElementById('Grab').click();
window.setTimeout(function() { pushSubmit(max, ++count) },3000);
}
}
//start the process with the max number of iterations it should perform
pushSubmit(50);
Example
I have created a loop, inside there is an if statment but it doesnt seem to execute more than once, but the same loop instead with a WHILE statment works but i really need to be an if statement.
function lines ()
{
for( SS = 0; SS < 11; SS++)
{
while(freq1.text == slotCheck+SS && freq4.text == slotCheck+SS )
{
freq2.text = "Win";
break;
}
The above works but i need the below one to execute 11 times.
function lines ()
{
for( SS = 0; SS < 11; SS++)
{
if(freq1.text == slotCheck+SS && freq4.text == slotCheck+SS )
{
freq2.text = "Win";
break;
}
I dont get your question???
You can just remove the Break; statement and your loop will be executed 11 times.
I think I get your question now.
You need to change 'break' to 'continue' to get it to run 11 times, and still skip other conditionals.
The Problem was my Pc, when i had restarted my machine everything was fine again. the loops and the code are correct anyways so my fustration was a hardware issue, (RAM) got plenty of it but its faulty as im experiencing missing files at random related to ram
sorry to have confused you guys
There are some nice examples about file uploading at HTML5 Rocks but there are something that isn't clear enough for me.
As far as i see, the example code about file slicing is getting a specific part from file then reading it. As the note says, this is helpful when we are dealing with large files.
The example about monitoring uploads also notes this is useful when we're uploading large files.
Am I safe without slicing the file? I meaning server-side problems, memory, etc. Chrome doesn't support File.slice() currently and i don't want to use a bloated jQuery plugin if possible.
Both Chrome and FF support File.slice() but it has been prefixed as File.webkitSlice() File.mozSlice() when its semantics changed some time ago. There's another example of using it here to read part of a .zip file. The new semantics are:
Blob.webkitSlice(
in long long start,
in long long end,
in DOMString contentType
);
Are you safe without slicing it? Sure, but remember you're reading the file into memory. The HTML5Rocks tutorial offers chunking the upload as a potential performance improvement. With some decent server logic, you could also do things like recovering from a failed upload more easily. The user wouldn't have to re-try an entire 500MB file if it failed at 99% :)
This is the way to slice the file to pass as blobs:
function readBlob() {
var files = document.getElementById('files').files;
var file = files[0];
var ONEMEGABYTE = 1048576;
var start = 0;
var stop = ONEMEGABYTE;
var remainder = file.size % ONEMEGABYTE;
var blkcount = Math.floor(file.size / ONEMEGABYTE);
if (remainder != 0) blkcount = blkcount + 1;
for (var i = 0; i < blkcount; i++) {
var reader = new FileReader();
if (i == (blkcount - 1) && remainder != 0) {
stop = start + remainder;
}
if (i == blkcount) {
stop = start;
}
//Slicing the file
var blob = file.webkitSlice(start, stop);
reader.readAsBinaryString(blob);
start = stop;
stop = stop + ONEMEGABYTE;
} //End of loop
} //End of readblob