ATM | Auto Tune Models - A multi-tenant , multi-data system | Machine Learning library
kandi X-RAY | ATM Summary
Support
Quality
Security
License
Reuse
- Define the tables
- Load data from a csv file
- Get local path to data directory
- Wrapper for download
- Get argument parser
- Compute metrics for each class
- Compute metrics for binary classification
- Calculate ROC curve
- Generate a matrix for the per class
- Create EC2 instances
- Load the selector
- Create an argument parser
- Show the status of the ATM process
- Retrieves an argument from the given arguments
- Setup logging
- Get the list of active instances
- Determine if a datarun is done
- Perform a work
- Loads a classifier from the database
- Restarts the ATM process
- Enter a dataset configuration
- Return a list of method methods available on the dataset
- Downloads a demo dataset
- Serve the application
- List datasets
- Load metrics for a classifier
ATM Key Features
ATM Examples and Code Snippets
def pressure_conversion(value: float, from_type: str, to_type: str) -> float: """ Conversion between pressure units. >>> pressure_conversion(4, "atm", "pascal") 405300 >>> pressure_conversion(1, "pascal", "psi") 0.00014401981999999998 >>> pressure_conversion(1, "bar", "atm") 0.986923 >>> pressure_conversion(3, "kilopascal", "bar") 0.029999991892499998 >>> pressure_conversion(2, "megapascal", "psi") 290.074434314 >>> pressure_conversion(4, "psi", "torr") 206.85984 >>> pressure_conversion(1, "inHg", "atm") 0.0334211 >>> pressure_conversion(1, "torr", "psi") 0.019336718261000002 >>> pressure_conversion(4, "wrongUnit", "atm") Traceback (most recent call last): File "/usr/lib/python3.8/doctest.py", line 1336, in __run exec(compile(example.source, filename, "single", File "", line 1, in pressure_conversion(4, "wrongUnit", "atm") File "", line 67, in pressure_conversion ValueError: Invalid 'from_type' value: 'wrongUnit' Supported values are: atm, pascal, bar, kilopascal, megapascal, psi, inHg, torr """ if from_type not in PRESSURE_CONVERSION: raise ValueError( f"Invalid 'from_type' value: {from_type!r} Supported values are:\n" + ", ".join(PRESSURE_CONVERSION) ) if to_type not in PRESSURE_CONVERSION: raise ValueError( f"Invalid 'to_type' value: {to_type!r}. Supported values are:\n" + ", ".join(PRESSURE_CONVERSION) ) return ( value * PRESSURE_CONVERSION[from_type].from_ * PRESSURE_CONVERSION[to_type].to )
def pressure_and_volume_to_temperature( pressure: float, moles: float, volume: float ) -> float: """ Convert pressure and volume to temperature. Ideal gas laws are used. Temperature is taken in kelvin. Volume is taken in litres. Pressure has atm as SI unit. Wikipedia reference: https://en.wikipedia.org/wiki/Gas_laws Wikipedia reference: https://en.wikipedia.org/wiki/Pressure Wikipedia reference: https://en.wikipedia.org/wiki/Temperature >>> pressure_and_volume_to_temperature(0.82, 1, 2) 20 >>> pressure_and_volume_to_temperature(8.2, 5, 3) 60 """ return round(float((pressure * volume) / (0.0821 * moles)))
def moles_to_volume(pressure: float, moles: float, temperature: float) -> float: """ Convert moles to volume. Ideal gas laws are used. Temperature is taken in kelvin. Volume is taken in litres. Pressure has atm as SI unit. Wikipedia reference: https://en.wikipedia.org/wiki/Gas_laws Wikipedia reference: https://en.wikipedia.org/wiki/Pressure Wikipedia reference: https://en.wikipedia.org/wiki/Temperature >>> moles_to_volume(0.82, 3, 300) 90 >>> moles_to_volume(8.2, 5, 200) 10 """ return round(float((moles * 0.0821 * temperature) / (pressure)))
Trending Discussions on ATM
Trending Discussions on ATM
QUESTION
So basically the goal is to combine these to functions into one or make it compatible with each other cause atm there is errors when it comes to the part when the path of the chosen file is not refer to in the same manner as the path of the found file within the loop if available in the folder.
So I know why I'm getting the error please see below 'HERE IS WHERE I GET THE ERROR' but I cant write the proper code to find my way out of the situation.
'main code that run is doing something like search for file within folder,
'loop and get the latest file and generates a path and name for next
'function which is to copy a sheet from the found file over to the main
'workbook and so.
'What I'm trying to to is to build a failsafe, lets say file is not pushed
'or placed whin this predestinated folder, then instead of doing nothing,
'dialog box opens up and files gets chosen instead.
Option Explicit
Sub ImportAndFormatData()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Const sFolderPath As String = "C:\Temp\"
'Search for newest file
Dim sFileName As String: sFileName = Dir(sFolderPath & "_pr11*.xlsx")
If Len(sFileName) = 0 Then Call OpenDialogBox
Dim cuDate As Date, sFileDate As Date, cuPath As String, sFilePath As String
Do Until Len(sFileName) = 0
cuPath = sFolderPath & sFileName
cuDate = FileDateTime(cuPath)
'Debug.Print "Current: " & cuDate & " " & cuPath ' print current
If cuDate > sFileDate Then
sFileDate = cuDate
sFilePath = cuPath
End If
sFileName = Dir
Loop
'Debug.Print "Result: " & sFileDate & " " & sFilePath ' print result
'Open newest file - HERE IS WHERE I GET THE ERROR
Dim closedBook As Workbook: Set closedBook = Workbooks.Open(sFilePath)
closedBook.Sheets("Analyse").Copy After:=ThisWorkbook.Sheets("PR11_P3")
closedBook.Close SaveChanges:=False
'code dose not end here but that part don't need to be included here since
'its just formatting
End Sub
And here is function for OpenDialogBox, I'm tying to enforce just a specific titel (cause only this file/rapport is correct source for the entire code (or rather rest of the code) but I cant figure this part out either, please see below, GIVES ERROR DOSENT WORK)
Sub OpenDialogBox()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.Filters.Clear
.Title = "Välj valfri PR11"
.Filters.Add "Excel filer", "_pr11*.xlsx?", 1 'GIVES ERROR DOSENT WORK
.AllowMultiSelect = False
If .Show = True Then
Debug.Print .SelectedItems(1)
Debug.Print Dir(.SelectedItems(1))
End If
End With
End Sub
ANSWER
Answered 2022-Apr-08 at 14:28This combines both the Dir()
and FileDialog
approaches:
Sub ImportAndFormatData()
Dim fSelected As String, wb As Workbook
fSelected = InputFile()
If Len(fSelected) > 0 Then
Set wb = Workbooks.Open(fSelected)
wb.Sheets("Analyse").Copy After:=ThisWorkbook.Sheets("PR11_P3")
wb.Close False
End If
End Sub
Function InputFile() As String
Const SRC_FOLDER As String = "C:\Temp\"
Dim f, fSelected As String, latestDate As Date, fdt
f = Dir(SRC_FOLDER & "*_pr11*.xlsx") 'first check the configured folder for a match
If Len(f) > 0 Then
'found matching file at specified path: loop for the newest file
Do While Len(f) > 0
fdt = FileDateTime(SRC_FOLDER & f)
If fdt > latestDate Then
fSelected = SRC_FOLDER & f
latestDate = fdt
End If
f = Dir()
Loop
InputFile = fSelected
Else
'no match at specified path - allow user selection
With Application.FileDialog(msoFileDialogFilePicker)
.Filters.Clear
.Title = "Välj valfri PR11"
.Filters.Add "Excel filer", "*.xlsx" 'filter only allows extension: no filename wildcards...
.AllowMultiSelect = False
If .Show Then InputFile = .SelectedItems(1)
End With
End If
End Function
QUESTION
I am porting C# app into C++ linux app. I am confused with construction and destruction in "modern" (C++11 ?). I always thought you have to use new/delete
but now it appears C++ recommendation is not to do so (is this correct or I read a wrong blog?).
What I have roughly (there are 6 subclasses of B
and BRec
atm):
class ARec : public BRec
class A : public B
. . .
class Factory
BRec GetRecord(WrapperStruct s)
{
if(s.Type == 'A')
{
A* a = (A*)s.Data;
auto rec = ARec((ushort)a->Num);
rec.OtherField = a.OtherField;
return rec;
}
. . .
main
// separate pthread
void* Logger(void* arg) {
int* thread_state = (int*)arg;
auto f = Factory();
WrapperStruct item;
while (true)
{
q->try_dequeue(item);
auto rec = f.GetRecord(item);
auto bytes = f.GetBytes(rec);
// write bytes to file ...
delete bytes;
if(*thread_state == -1)
pthread_exit(0);
}
Question - how does compiler would know when to delete s.Data
in factory method? Same - rec
if it was created in a class method and then crossed to other method (while
in Logger)? Is there a simple guide how to manage variables' memory in C++11 ?
EDIT: s.Data
contains ref to an object created in a 3rd party dll and can be of different types hence the s.Type
field
ANSWER
Answered 2022-Mar-24 at 20:17Smart pointers are the key.
std::shared_ptr foo = std::make_shared();
std::unique_ptr bar = std::make_unique();
Shared pointers can be copied. They do reference counting. When the reference count drops to zero, they'll delete their contents automatically.
Unique pointers can't be copied. They can be copied by reference. When the unique pointer goes out of reference, it frees the object for you.
So it works a lot like Java now.
void notAMemoryLeak() {
std::shared_ptr foo = std::make_shared();
}
Other than that, you treat them like pointers. The syntax for their use at this point is identical, except you're passing smart pointers, not Foo *.
void myFunct(std::unique_ptr &foo) {
cout << "Foo: " << foo->getName() << "\n";
}
The make_shared
and make_unique
can take the same arguments as any of your Foo's constructors, so feel free to pass stuff.
I do one more thing:
class Foo {
public:
typedef std::shared_ptr Pointer;
...
};
Foo::Pointer foo = std::make_shared();
Sometimes I also create static methods to make it even cleaner. This is stylistic and not necessary. Some people might fault me. But it's clean and easy to read.
QUESTION
I am trying to create a sample of 500 values between (and including) 60 and 126. ATM I've got:
random.sample(range(60,126),500)
but the syntax is invalid given the sample size is larger than my specified range.
Should I be using 'list' or some sort of iteration instead and if so, how?
ANSWER
Answered 2022-Mar-20 at 06:08You could use random.choices
:
random.choices(range(60, 126), k=500)
This will return a list of 500 values where each value comes from the provided range. Values will be sampled from the same collection in each pick, so each value could appear more than once (even if the collection size is greater than k
).
QUESTION
So I have sampled a set of lakes at x timepoints throughout the year. I also have deployed loggers etc. in the water and I want to use daily averages from these loggers, at the timepoint of the visit to x days/hours before. Sometimes I also just grab the a sample for the timepoint of the visit.
This is my solution, it works just fine but since I experiment alot with some model assumptions and perform sensitivity analyses it operates unsatisfactory slow.
I seem to have solved most of my R problems with loops and I often encounter more efficient scripts, it would be very interesting to see some more effective alternatives to my code.
Below code just generates some dummy data..
library(dplyr)
library(lubridate)
do.pct.sat <- function(x,y,z){
t <- x
do <- y
p <- z
atm <- (p*100)/101325
do.sat <- atm*exp(-139.34411+157570.1/(t+273.15)-66423080/(t+273.15)^2+12438000000/(t+273.15)^3-862194900000/(t+273.15)^4)
do.pct.sat <- (do/do.sat)*100
return(do.pct.sat)
}#function for calculating the % oxygen saturation
#here's some dummy date resembling real data
date.initial <- as.POSIXct("2022-06-01")#deployment date
date.end <- as.POSIXct("2022-10-01")#date of retrieval
id <- c("a","b","c")#lake id
lake <- list()#make dataset list for each lake
s <- list()#list of dataframes for the samples from the lake logger timelines
#loop below generates dummy data. this is not part of the real script that I want to improve.
for(i in 1:3){
datetime <- seq(from = date.initial,to = date.end,by=10*60)#10 minute intervals from deploy to retrieve
l <- length(datetime)#vector length of datetime
#set dummy data
do <- rnorm(l,mean = 10,sd=3)#o2 conc.
pressure <- rnorm(l,mean = 980,sd=50)#baro pressure
temp <- rnorm(l,mean=15,sd=5)#water temp
k.z <- rnorm(l,mean=0.35,sd=0.1)#gas exchange koeff / mixed layer depth
dosat.pct <- do.pct.sat(temp,do,pressure)#oxygen sat in %
iso <- as.data.frame(cbind(datetime,do,dosat.pct,temp,pressure,k.z))#bind dummy dataframe to resemble real data
iso$datetime <- as.POSIXct(iso$datetime,origin = "1970-01-01")
lake[[i]] <- iso#save the data frame to the lake logger list
samples <- as.POSIXct(sample((date.initial+5*24*60*60):date.end, 7, replace=FALSE),origin = "1970-01-01")#randomize 7 timepoints
s[[i]] <- as.data.frame(samples)#save it in empty data frame
s[[i]]$lake <- id[i]
}
names(lake) <- id
samples <- bind_rows(s)
samples$samples <- round_date(samples$samples,unit="10 minutes")#rounds my random samples to closest 10 minute
Below is the function that I want to effectivize (same library). I think it operates slow because I take one date at a time, before taking the next;
sample.lakes <- function(average=3){
dts <- list()#empty list
for(i in 1:length(lake)){
print(id[i])
data = lake[[i]]
y <- samples[grepl(id[i],samples$lake),]
dates <- y$samples
#empty vectors to fill with values sampled in loop
avg.kz <- vector()
sd.kz <- vector()
do.mgl <- vector()
dosat.pct <- vector()
temp.c <- vector()
for (k in 1:length(dates)){
print(k)
#below I filter the logger data to contain timepoint of sampling minus number of days I want the average from 'averages'.
prior.days = filter(data, datetime > as.POSIXct(dates[k])-(24*60*60)*average & datetime < as.POSIXct(dates[k]))
#fill the empty vectors with value I desire, mean and sd k.z and point sample of the other variables.
avg.kz[k] = mean(prior.days$k.z)
sd.kz[k] = sd(prior.days$k.z)
temp.c[k] <- data[grepl(dates[k],data$datetime),]$temp
do.mgl[k] <- data[grepl(dates[k],data$datetime),]$do
dosat.pct[k] <- data[grepl(dates[k],data$datetime),]$dosat.pct
}
sd.kz[is.na(sd.kz)] <- 0
#add them to data frame y
y$dosat.pct <- dosat.pct
y$do.mgl <- do.mgl
y$temp.c <- temp.c
y$avg.kz <- avg.kz
y$sd.kz <- sd.kz
dts[[i]] <- y#add to single-row dataframe
}
iso <- bind_rows(dts)#make a complete dataframe with samples.
return(iso)
}
iso <- sample.lakes(average=4)#do not set average to > 5 in this example script
I would appreciaty any suggestions alot!
ANSWER
Answered 2022-Mar-19 at 22:01My guess is that this part using grepl
:
data[grepl(dates[k],data$datetime),]
inside your inner for
loop is slow.
Couldn't you instead try just seeing if the datetimes are the same with ==
?
In addition, you only need to subset data
once.
Try this as an alternative:
for (k in 1:length(dates)){
print(k)
prior.days = filter(data, datetime > as.POSIXct(dates[k])-(24*60*60)*average & datetime < as.POSIXct(dates[k]))
avg.kz[k] = mean(prior.days$k.z)
sd.kz[k] = sd(prior.days$k.z)
sub_data <- data[data$datetime == dates[k], ]
temp.c[k] <- sub_data$temp
do.mgl[k] <- sub_data$do
dosat.pct[k] <- sub_data$dosat.pct
}
QUESTION
I have a question about the definition of the synchronises-with relation in the C++ memory model when relaxed and acquire/release accesses are mixed on one and the same atomic variable. Consider the following example consisting of a global initialiser and three threads:
int x = 0;
std::atomic atm(0);
[thread T1]
x = 42;
atm.store(1, std::memory_order_release);
[thread T2]
if (atm.load(std::memory_order_relaxed) == 1)
atm.store(2, std::memory_order_relaxed);
[thread T3]
int value = atm.load(std::memory_order_acquire);
assert(value != 1 || x == 42); // Hopefully this is guaranteed to hold.
assert(value != 2 || x == 42); // Does this assert hold necessarily??
My question is whether the second assert in T3
can fail under the C++ memory model. Note that the answer to this SO question suggests that the assert could not fail if T2
used load/acquire and store/release; please correct me if I got this wrong. However, as stated above, the answer seems to depend on how exactly the synchronises-with relation is defined in this case. I was confused by the text on cppreference, and I came up with the following two possible readings.
The second assert fails. The store to
atm
inT1
could be conceptually understood as storing1_release
where_release
is annotation specifying how the value was stored; along the same lines, the store inT2
could be understood as storing2_relaxed
. Hence, if the load inT3
returns2
, the thread actually read2_relaxed
; thus, the load inT3
does not synchronise-with the store inT1
and there is no guarantee thatT3
seesx == 42
. However, if the load inT3
returns1
, then1_release
was read, and therefore the load inT3
synchronises-with the store inT1
andT3
is guaranteed to seex == 42
.The second assert success. If the load in
T3
returns2
, then this load reads a side-effect of the relaxed store inT2
; however, this store ofT2
is present in the modification order ofatm
only if the modification order ofatm
contains a preceding store with a release semantics. Therefore, the load/acquire inT3
synchronises-with the store/release ofT1
because the latter necessarily precedes the former in the modification order ofatm
.
At first glance, the answer to this SO question seems to suggest that my reading 1 is correct. However, that answer seems to be different in a subtle way: all stores in the answer are release, and the crux of the question is to see that load/acquire and store/release establishes synchronises-with between a pair of threads. In contrast, my question is about how exactly synchronises-with is defined when memory orders are heterogeneous.
I actually hope that reading 2 is correct since this would make reasoning about concurrency easier. Thread T2
does not read or write any memory other than atm
; therefore, T2
itself has no synchronisation requirements and should therefore be able to use relaxed memory order. In contrast, T1
publishes x
and T3
consumes it -- that is, these two threads communicate with each other so they should clearly use acquire/release semantics. In other words, if interpretation 1 turns out to be correct, then the code T2
cannot be written by thinking only about what T2
does; rather, the code of T2
needs to know that it should not "disturb" synchronisation between T1
and T3
.
In any case, knowing what exactly is sanctioned by the standard in this case seems absolutely crucial to me.
ANSWER
Answered 2022-Mar-17 at 14:01Because you use relaxed ordering on a separate load & store in T2, the release sequence is broken and the second assert can trigger (although not on a TSO platform such as X86).
You can fix this by either using acq/rel ordering in thread T2 (as you suggested) or by modifying T2 to use an atomic read-modify-write operation (RMW), like this:
[Thread T2]
int ret;
do {
int val = 1;
ret = atm.compare_exchange_weak(val, 2, std::memory_order_relaxed);
} while (ret != 0);
The modification order of atm
is 0-1-2 and T3 will pick up on either 1 or 2 and no assert can fail.
Another valid implementation of T2 is:
[thread T2]
if (atm.load(std::memory_order_relaxed) == 1)
{
atm.exchange(2, std::memory_order_relaxed);
}
Here the RMW itself is unconditional and it must be accompanied by an if-statement & (relaxed) load to ensure that the modification order of atm
is 0-1 or 0-1-2
Without the if-statement, the modification order could be 0-2 which can cause the assert to fail. (This works because we know there is only one other write in the whole rest of the program. Separate if()
/ exchange
is of course not in general equivalent to compare_exchange_strong
.)
In the C++ standard, the following quotes are related:
[intro.races]
A release sequence headed by a release operation A on an atomic object M is a maximal contiguous subsequence of side effects in the modification order of M, where the first operation is A, and every subsequent operation is an atomic read-modify-write operation.
[atomics.order]
An atomic operation A that performs a release operation on an atomic object M synchronizes with an atomic operation B that performs an acquire operation on M and takes its value from any side effect in the release sequence headed by A.
this question is about why an RMW works in a release sequence.
QUESTION
I feel like it was easier to get subcollection in v8 ,It's been like 2 days trying to do it the new way but I gave up.
Im building a simple react social media app for learning purposes. where each user logs in and be able to post some text (and images but not atm), I have a main collection for Users and it has the users ID .each of these users have a collection called Posts and it contains all the user posts.
I can do so by entering the UID of each user like so
so what can i do to access the Users collection then get ALL the users and be able to access the Posts subcollection?
ps : sorry if any part of this question is unclear ,english isn't my first language and it's my first time posting here. appreciate any help!.
ANSWER
Answered 2021-Sep-17 at 12:23If you want to fetch posts from all the users, you are looking for collectionGroup
queries using which you can fetch documents in all the sub-collections named as 'posts'. You can run a collectionGroup
query using Modular SDK (V9) as shown below:
import { getFirestore, getDocs, collectionGroup } from "firebase/firestore"
const db = getFirestore()
const allPosts = await getDocs(collectionGroup(db, "posts"))
QUESTION
Please note that I am a complete beginner at C++. I'm trying to write a simple program for an ATM and I have to account for all errors. User may use only integers for input so I need to check if input value is indeed an integer, and my program (this one is shortened) works for the most part.
The problem arises when I try to input a string value instead of an integer while choosing an operation. It works with invalid value integers, but with strings it creates an infinite loop until it eventually stops (unless I add system("cls")
, then it doesn't even stop), when it should output the same result as it does for invalid integers:
Invalid choice of operation.
Please select an operation:
1 - Balance inquiry
7 - Return card
Enter your choice and press return:
Here is my code:
#include
#include
using namespace std;
bool isNumber(string s) //function to determine if input value is int
{
for (int i = 0; i < s.length(); i++)
if (isdigit(s[i]) == false)
return false;
return true;
}
int ReturnCard() //function to determine whether to continue running or end program
{
string rtrn;
cout << "\nDo you wish to continue? \n1 - Yes \n2 - No, return card" << endl;
cin >> rtrn;
if (rtrn == "1" and isNumber(rtrn)) { return false; }
else if (rtrn == "2" and isNumber(rtrn)) { return true; }
else {cout << "Invalid choice." << endl; ReturnCard(); };
return 0;
}
int menu() //function for operation choice and execution
{
int choice;
do
{
cout << "\nPlease select an operation:\n" << endl
<< " 1 - Balance inquiry\n"
<< " 7 - Return card\n"
<< "\nEnter your choice and press return: ";
int balance = 512;
cin >> choice;
if (choice == 1 and isNumber(to_string(choice))) { cout << "Your balance is $" << balance; "\n\n"; }
else if (choice == 7 and isNumber(to_string(choice))) { cout << "Please wait...\nHave a good day." << endl; return 0; }
else { cout << "Invalid choice of operation."; menu(); }
} while (ReturnCard()==false);
cout << "Please wait...\nHave a good day." << endl;
return 0;
}
int main()
{
string choice;
cout << "Insert debit card to get started." << endl;
menu();
return 0;
}
I've tried every possible solution I know, but nothing seems to work.
***There is a different bug, which is that when I get to the "Do you wish to continue?" part and input any invalid value and follow it up with 2 (which is supposed to end the program) after it asks again, it outputs the result for 1 (continue running - menu etc.). I have already emailed my teacher about this and this is not my main question, but I would appreciate any help.
Thank you!
ANSWER
Answered 2022-Feb-04 at 10:56There are a few things mixed up in your code. Always try to compile your code with maximum warnings turned on, e.g., for GCC add at least the -Wall
flag. Then your compiler would warn you of some of the mistakes you made.
First, it seems like you are confusing string choice
and int choice
. Two different variables in different scopes. The string
one is unused and completely redundant. You can delete it and nothing will change.
In menu, you say cin >> choice;
, where choice
is of type int
. The stream operator >>
works like this: It will try to read as many characters as it can, such that the characters match the requested type. So this will only read ints.
Then you convert your valid int
into a string and call isNumber()
- which will alway return true.
So if you wish to read any line of text and handle it, you can use getline()
:
string inp;
std::getline(std::cin, inp);
if (!isNumber(inp)) {
std::cout << "ERROR\n";
return 1;
}
int choice = std::stoi(inp); // May throw an exception if invalid range
See stoi
Your isNumber()
implementation could look like this:
#include
bool is_number(const string &inp) {
return std::all_of(inp.cbegin(), inp.cend(),
[](unsigned char c){ return std::isdigit(c); });
}
If you are into that functional style, like I am ;)
EDIT:
Btw., another bug which the compiler warns about: cout << "Your balance is $" << balance; "\n\n";
- the newlines are separated by ;
, so it's a new statement and this does nothing. You probably wanted the <<
operator instead.
Recursive call bug:
In { cout << "Invalid choice of operation."; menu(); }
and same for ReturnCard()
, the function calls itself (recursion). This is not at all what you want! This will start the function over, but once that call has ended, you continue where that call happened. What you want in menu()
is to start the loop over. You can do that with the continue
keyword. You want the same for ReturnCard()
. But you need a loop there. And now, that I read that code, you don't even need to convert the input to an integer. All you do is compare it. So you can simply do:
string inp;
std::getline(std::cin, inp);
if (inp == "1" || inp == "2") {
// good
} else {
// Invalid
}
Unless that is part of your task.
QUESTION
So I'm trying to use a single sheet as a price db to update prices in WooCommerce through the Woo API, using fetch. It works, my problem is that it apparently works depending on the size of the dataset? I'm not sure because I can't understand the error.
UPDATED CODE
function getDataloopwoo() {
const ck = 'ck_fd0992917fbbb0464d4146ad5861f51adcb36369';
const cs = 'cs_6f8061efce415355fb6cac520bd1506ad126578a';
const website = 'https://www.atopems-desarrollo.com.ar';
const optionsGet =
{
'method': 'GET',
'contentType': 'application/x-www-form-urlencoded;charset=UTF-8',
'muteHttpExceptions': true,
};
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
const codigos = sheet.getRange('A2:A').getValues();
const precios = sheet.getRange('B2:B').getValues();
const data = codigos.map(function(codigos, indice) {
return {
sku: codigos[0],
price: precios[indice][0]
}
})
const container = [];
var surl = website + '/wp-json/wc/v3/products?consumer_key=' + ck + '&consumer_secret=' + cs + '&per_page=100' + '&orderby=id' + '&order=asc' + '&status=publish' + '&page=1';
var url = surl
Logger.log(url)
var result = UrlFetchApp.fetch(url, optionsGet);
var headers = result.getAllHeaders();
var total_pages = 45;
var pages_count = 0;
while (pages_count < total_pages) {
if (result.getResponseCode() == 200) {
var wooProducts = JSON.parse(result.getContentText());
//Logger.log(result.getContentText());
}
for (var i = 0; i < wooProducts.length; i++) {
//Logger.log(i);
container.push({
sku: wooProducts[i]['sku'],
id: wooProducts[i]['id'],
price: wooProducts[i]['price']
});
}
pages_count++;
if (pages_count < total_pages) {
var surl = website + '/wp-json/wc/v3/products?consumer_key=' + ck + '&consumer_secret=' + cs + '&per_page=100' + '&orderby=id' + '&order=asc' + '&status=publish' + '&page=' + (pages_count + 1);
var url = surl
var result = UrlFetchApp.fetch(url, optionsGet);
Logger.log(url);
}
}
var data_obj = {}
for (let obj of data)
data_obj[obj.sku] = {'price': obj.price};
console.log(data_obj);
var container_obj = {}
for (let obj of container)
container_obj[obj.sku] = {'price': obj.price, 'id': obj.id};
console.log(container_obj);
const output = [];
for (let sku in container_obj) {
let data_subObj = data_obj[sku];
let container_subObj = container_obj[sku];
if (data_subObj.price > container_subObj.price) {
output.push({'id':container_subObj.id, 'regular_price':data_subObj.price});
}
}
console.log(output);
var temporary, chunk = 100;
for (let i = 0;i < output.length; i += chunk) {
temporary = output.slice(i, i + chunk);
var payloadUp = {
update: temporary
}
var headPost =
{
'method' : 'POST',
'contentType': 'application/json',
'payload': JSON.stringify(payloadUp)
};
console.log(payloadUp);
var urlPost = website + '/wp-json/wc/v3/products/batch?consumer_key=' + ck + '&consumer_secret=' + cs;
var result = UrlFetchApp.fetch(urlPost, headPost);
console.log(urlPost);
if (result.getResponseCode() == 200) {
console.log(result.getContentText());
};
}
}
I use the var headers to get all headers but since I'm testing ATM I don't use it. So if I get around 15-20 products from WooCoommerce everything works like a charm, I get all product data, create a new array with sku, id and price. Then compare that array with an array from my sheets with the updated price value and then push sku, id and updated price to a new array and POST that array to woocommerce batch update. Works fine, if I try to process more I get this error:
TypeError: Cannot read property 'price' of undefined
I'm really wracking my brains mostly because I'm a total novice in JS.
I'll post the logs,
Logger.log(url);
https://atopems.com/wp-json/wc/v3/products?consumer_key=ck_xxx&consumer_secret=cs_xxx&per_page=100&orderby=id&order=asc&status=publish&page=51
console.log(data_obj);
Logging output too large. Truncating output. { '200': { price: 299.98 },
'201': { price: 156.9 },
'202': { price: 112.05 },
'203': { price: 100.58 },
'204': { price: 126.33 },
'205': { price: 126.53 },
'206': { price: 2858.42 },
'207': { price: 2336.79 },
'208': { price: 401.25 },
'209': { price: 378.32 },
'210': { price: 282.78 },
'211': { price: 252.21 },
'212': { price: 292.34 },
'213': { price: 309.53 },
'214': { price: 385.96 },
'215': { price: 554.1 },
console.log(container_obj);
Logging output too large. Truncating output. { '60026': { price: '2319.6', id: 24942 },
'60032': { price: '4050.7', id: 24943 },
'60033': { price: '4050.7', id: 24944 },
'60119': { price: '7195.72', id: 24945 },
BR9010: { price: '984.5', id: 24067 },
BR9013: { price: '1744.32', id: 24068 },
BR9014: { price: '1869.03', id: 24069 },
BR9015: { price: '1869.03', id: 24070 },
BR9016: { price: '984.5', id: 24071 },
BR9017: { price: '747.66', id: 24072 },
BR9026: { price: '664.52', id: 24073 },
BR9037: { price: '830.62', id: 24074 },
BR9042: { price: '830.62', id: 24075 },
BR9043: { price: '747.66', id: 24076 },
BR9048: { price: '1204.44', id: 24077 },
BR9049: { price: '955.23', id: 24078 },
BR9050: { price: '955.23', id: 24079 },
BR9052: { price: '1079.9', id: 24080 },
BR9055: { price: '955.23', id: 24081 },
BR9056: { price: '1266.63', id: 24082 },
BR9059: { price: '955.23', id: 24083 },
BR9067: { price: '830.62', id: 24084 },
BR9068: { price: '1349.13', id: 24085 }
The exact error
17:07:38 Error
TypeError: Cannot read property 'price' of undefined
getDataloopwoo @ JSONsheet.gs:63
The sheet in question, in case anyone wants to see the type of data I'm working with.
const data = codigos.map etc
uses 2 variables, SKU and PRICE, which are column A and B respectively in the sheet as simple objects.
EDIT:
Ok, Test sheet that can be copied with CK and CS Keys to a testing WooCommerce site.
https://docs.google.com/spreadsheets/d/14afFyj1geaNCWt_e4DE9S41wlgepWAtasK2z5_u1hdc/edit?usp=sharing
If run as is it can be reproduced without doing anything else.
Tried with 20 pages it works, with 45 it doesn't.
I'm not sure what more I could do to make it reproducible.
- I legit don't understand what could be the root of the problem.
ANSWER
Answered 2022-Jan-13 at 02:14- In your situation, it seems that the values of
sku
ofcontainer
is not existing in the values ofsku
ofdata_obj
. I thought that the reason for your issue might be due to this. - As a script for checking this, you can use
const res = container.filter(e => !data_obj[e.sku])
for your script. In this case,[ { sku: 'L4943-0ULT', id: 3195, price: '5083.33' } ]
is returned. When this value is searched from your sample Spreadsheet,l4943-0ult
is found. In this case, the character case is different. By this, your issue occurs. I resulted in the reason of your issue is due to this.
When this issue was removed, how about the following modification?
From:data_obj[obj.sku] = {'price': obj.price};
data_obj[isNaN(obj.sku) ? obj.sku.toUpperCase() : obj.sku] = {'price': obj.price};
And,
From:container_obj[obj.sku] = {'price': obj.price, 'id': obj.id};
container_obj[isNaN(obj.sku) ? obj.sku.toUpperCase() : obj.sku] = { 'price': obj.price, 'id': obj.id };
And also, in order to avoid no keys in the if statement, how about adding the following modification?
From:if (data_subObj.price > container_subObj.price) {
if (data_subObj && data_subObj.price > container_subObj.price) {
QUESTION
Ive go a request body that is an json array of objects something like,
{
"data": [
{
"id": "1234",
"someNestedObject": {
"someBool": true,
"randomNumber": 488
},
"timestamp": "2021-12-13T02:43:44.155Z"
},
{
"id": "4321",
"someNestedObject": {
"someBool": false,
"randomNumber": 484
},
"timestamp": "2018-11-13T02:43:44.155Z"
}
]
}
I want to get a count of the objects in the array and split them into seperate json outputs to pass onto the next service. Im doing this atm by unmarshalling the original json request body and and then looping over the the elements marshalling each one again and attaching it to whatever outgoing message is being sent. Something like,
requestBodyBytes := []bytes(JSON_INPUT_STRING)
type body struct {
Foo []json.RawMessage `json:"foo"`
}
var inputs body
_ = json.Unmarshal(requestBodyBytes, &inputs)
for input := range inputs {
re, _ := json.Marshal(m)
... do something with re
}
What Im seeing though is the byte array of the before and after is different, even though the string representation is the same. I am wondering if there is a way to do this without altering the encoding or whatever is happening here to change the bytes to safeguard against any unwanted mutations? The actual json objects in the array will all have different shapes so I cant use a structured json definition with field validations to help.
Also, the above code is just an example of whats happening so if there are spelling or syntax errors please ignore them as the actual code works as described.
ANSWER
Answered 2022-Jan-07 at 15:06If you use json.RawMessage
, the JSON source text will not be parsed but stored in it as-is (it's a []byte
).
So if you want to distribute the same JSON array element, you do not need to do anything with it, you may "hand it over" as-is. You do not have to pass it to json.Marshal()
, it's already JSON marshalled text.
So simply do:
for _, input := range inputs.Foo {
// input is of type json.RawMessage, and it's already JSON text
}
If you pass a json.RawMessage
to json.Marshal()
, it might get reencoded, e.g. compacted (which may result in a different byte sequence, but it will hold the same data as JSON).
Compacting might even be a good idea, as the original indentation might look weird taken out of the original context (object and array), also it'll be shorter. To simply compact a JSON text, you may use json.Compact()
like this:
for _, input := range inputs.Foo {
buf := &bytes.Buffer{}
if err := json.Compact(buf, input); err != nil {
panic(err)
}
fmt.Println(buf) // The compacted array element value
}
If you don't want to compact it but to indent the array elements on their own, use json.Indent()
like this:
for _, input := range inputs.Foo {
buf := &bytes.Buffer{}
if err := json.Indent(buf, input, "", " "); err != nil {
panic(err)
}
fmt.Println(buf)
}
Using your example input, this is how the first array element would look like (original, compacted and indented):
Orignal:
{
"id": "1234",
"someNestedObject": {
"someBool": true,
"randomNumber": 488
},
"timestamp": "2021-12-13T02:43:44.155Z"
}
Compacted:
{"id":"1234","someNestedObject":{"someBool":true,"randomNumber":488},"timestamp":"2021-12-13T02:43:44.155Z"}
Indented:
{
"id": "1234",
"someNestedObject": {
"someBool": true,
"randomNumber": 488
},
"timestamp": "2021-12-13T02:43:44.155Z"
}
Try the examples on the Go Playground.
Also note that if you do decide to compact or indent the individual array elements in the loop, you may create a simple bytes.Buffer
before the loop, and reuse it in each iteration, calling its Buffer.Reset()
method to clear the previous array's data.
It could look like this:
buf := &bytes.Buffer{}
for _, input := range inputs.Foo {
buf.Reset()
if err := json.Compact(buf, input); err != nil {
panic(err)
}
fmt.Println("Compacted:\n", buf)
}
QUESTION
I was tasked to create an ATM mock program and my problem is overwriting the money and PIN variables with the information that the user will enter.
Here it is:
#include
using namespace std;
void Check(int money) { cout << "Your current balance is: " << money << endl; }
void Deposit(int money) {
int deposit;
cout << "Please enter the amount of cash you wish to deposit.\n";
cin >> deposit;
money += deposit;
cout << "Your new balance is: " << money << endl;
}
void Withdraw(int money) {
int withdraw;
cout << "Please enter the amount of cash you wish to withdraw.\n";
cin >> withdraw;
money -= withdraw;
cout << "Your new balance is: " << money << endl;
}
void Interest(int money) {
money += money * 0.05;
cout << "Your money with interest is: " << money << endl;
}
void Penalty(int money) {
if (money < 5000) {
money -= money * 0.02;
cout << "Your penalty is: " << money << endl;
} else
cout << "Your account will not incur a penalty because you are above the "
"minimum threshold.\n";
}
void ChangePIN(int PIN) {
int p;
cout << "Enter a new PIN: ";
cin >> p;
PIN = p;
cout << "Your new PIN is: " << PIN << endl;
}
int main() {
int money = 5000, PIN = 1234, EPIN;
cout << "Enter your PIN (Default PIN is 1234): \n";
cin >> EPIN;
if (EPIN == PIN) {
int choice;
cout << "Welcome!\n"
<< "1 - Check available balance \n"
<< "2 - Deposit cash \n"
<< "3 - Withdraw cash \n"
<< "4 - Compute for the interest of your account(5%)\n"
<< "5 - Compute for the penalty of having a balance below 5000 (2%) \n"
<< "6 - Change your PIN\n"
<< "7 - Exit\n"
<< "Your choice: ";
cin >> choice;
switch (choice) {
case 7: {
break;
}
{
case 1: {
Check(money);
break;
}
case 2: {
Deposit(money);
break;
}
case 3: {
Withdraw(money);
break;
}
case 4: {
Interest(money);
break;
}
case 5: {
Penalty(money);
break;
}
case 6: {
ChangePIN(PIN);
break;
}
}
}
return 0;
}
}
As you can see I'm pretty much a beginner at this. My problem is the money and PIN have the default values of 5000 and 1234 respectively. Now, I need to make the user be able to change these values but once I use return main() they get assigned the same starting values again, What would be the best workaround for this? I thought of using some sort of accumulator for this but I'd like some advice first.
ANSWER
Answered 2022-Jan-07 at 13:46You can simply do this by using a while loop.
Run an infinite while loop and break it whenever you want to exit from the program.
Here is the code:
#include
using namespace std;
void Check(int money) { cout << "Your current balance is: " << money << endl; }
void Deposit(int money) {
int deposit;
cout << "Please enter the amount of cash you wish to deposit.\n";
cin >> deposit;
money += deposit;
cout << "Your new balance is: " << money << endl;
}
void Withdraw(int money) {
int withdraw;
cout << "Please enter the amount of cash you wish to withdraw.\n";
cin >> withdraw;
money -= withdraw;
cout << "Your new balance is: " << money << endl;
}
void Interest(int money) {
money += money * 0.05;
cout << "Your money with interest is: " << money << endl;
}
void Penalty(int money) {
if (money < 5000) {
money -= money * 0.02;
cout << "Your penalty is: " << money << endl;
} else
cout << "Your account will not incur a penalty because you are above the "
"minimum threshold.\n";
}
int ChangePIN(int PIN) {
int p;
cout << "Enter a new PIN: ";
cin >> p;
cout << "Your new PIN is: " << PIN << endl;
return p;
}
int main() {
int money = 5000, PIN = 1234;
while(1){ // run an infinite loop
int EPIN;
cout << "Enter your PIN (Default PIN is 1234): \n";
cin >> EPIN;
if (EPIN == PIN) {
int choice;
cout << "Welcome!\n"
<< "1 - Check available balance \n"
<< "2 - Deposit cash \n"
<< "3 - Withdraw cash \n"
<< "4 - Compute for the interest of your account(5%)\n"
<< "5 - Compute for the penalty of having a balance below 5000 (2%) \n"
<< "6 - Change your PIN\n"
<< "7 - Exit\n"
<< "Your choice: ";
cin >> choice;
switch (choice) {
case 7: {
return 0; // breaking condition
}
{
case 1: {
Check(money);
break;
}
case 2: {
Deposit(money);
break;
}
case 3: {
Withdraw(money);
break;
}
case 4: {
Interest(money);
break;
}
case 5: {
Penalty(money);
break;
}
case 6: {
PIN = ChangePIN(PIN);
break;
}
}
}
}
}
return 0;
}
Does this answer your question?
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install ATM
Alternatively, with your virtualenv activated, you can clone the repository and install it from source by running make install on the stable branch:.
If you want to contribute to the project, a few more steps are required to make the project ready for development. First, please head to the GitHub page of the project and make a fork of the project under you own username by clicking on the fork button on the upper right corner of the page.
In this short tutorial we will guide you through a series of steps that will help you getting started with ATM by exploring its Python API.
Support
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesExplore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits
Save this library and start creating your kit
Share this Page