String color1 = moreColors.get(0);
String color2 = moreColors[0];
System.assertEquals(color1, color2);
// Iterate over a list to read elements
for(Integer i=0;i<colors.size();i++) {
// Write value to the debug log
System.debug(colors[i]);
}
I am learning Apex and just started what is meaning of line System.assertEquals(color1, color2); and what is mean by debug log here?
System.assert, System.assertEquals, System.assertNotEquals. I argue these are three of the most important method calls in Apex.
These are assert statements. They are used in testing to validate that the data you have matches your expectations.
System.assert tests an logical statement. If the statement evaluates to True, the code keeps running. If the statement evaluates to False, the code throws an exception.
System.assertEquals tests that two values are equal. If the two are equal, the code keeps running. If they are not equal, the code throws an exception.
System.assertNotEqual tests that two values are not equal. If the two are not equal, the code keeps running. If they are equal, the code throws an exception.
These are critical for completing system testing. In Apex Code, you must have 75% line test coverage. Many people do this by generating test code that simply covers 75% of their lines of code. However, this is an incomplete test. A good test class actually tests that the code does what you expect. This is really great to ensure that your code actually works. This makes debugging and regression testing far easier. For example. Lets create a method called square(Integer i) that squares the integer returned.
public static Integer square( Integer i ) {
return i * i;
}
A poor test method would simply be:
#isTest
public static void test_squar() {
square( 1 );
}
A good test method could be:
#isTest
public static void test_square() {
Integer i;
Integer ret_square;
i = 3;
ret_square = square( i );
System.assertEquals( i * i; ret_square );
}
How I would probably write it is like this:
#isTest
public static void test_square() {
for( Integer i = 0; i < MAX_TEST_RUNS; i++ ) {
System.assertEquals( i*i, square( i ) );
}
}
Good testing practices are integral to being a good developer. Look up more on Testing-Driven Development. https://en.wikipedia.org/wiki/Test-driven_development
Line by Line ...
//Get color in position 0 of moreColors list using the list get method store in string color1
String color1 = moreColors.get(0);
//Get color in position 0 of moreColors list using array notation store in string color2,
//basically getting the same value in a different way
String color2 = moreColors[0];
//Assert that the values are the same, throws exception if false
System.assertEquals(color1, color2);
// Iterate over a list to read elements
for(Integer i=0;i<colors.size();i++) {
// Write value to the debug log
System.debug(colors[i]);//Writes the value of color list ith position to the debug log
}
If you are running this code anonymously via the Developer console you can look for lines prefixed with DEBUG| to find the statements, for e.g.
16:09:32:001 USER_DEBUG 1|DEBUG| blue
More about system methods can be found at https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_system.htm#apex_System_System_methods
Related
I'm following tutorial from the official Microsoft learning page (https://learn.microsoft.com/en-us/azure/quantum/tutorial-qdk-explore-entanglement?pivots=ide-azure-portal) about quantum entanglement.
Basically, I copied an example posted there and I am getting error:
QS5026 The variable "numOnesQ1" cannot be reassigned here. In conditional blocks that depend on a measurement result, the target QuantinuumProcessor only supports reassigning variables that were declared within the block.
I understand what it says but it's just a copy from the official Microsoft tutorial. Am I missing something simple like imports, wrong settings? If not, how can I in other way set variables declared outside conditional blocks that depend on a measurement result?
Here is my code:
namespace Quantum.QuantumDream {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
operation GetRandomResult() : Result {
use q = Qubit();
H(q);
return M(q);
}
#EntryPoint()
operation TestBellState(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones':
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return number of |0> states, number of |1> states
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
}
This tutorial code is only supposed to run on a local simulator (using %simulate magic commands in a Jupyter Notebook). From the error message, it looks like you've tried to run it on one of Quantinuum targets, which have some limitations on the kinds of things you can do in the code. To run equivalent code on Quantinuum, you'd need to define an operation for just the body of the loop (preparing a state and measuring it) and run it as a job - the cloud targets will take care of the loop themselves, running your code multiple times and returning to you a histogram of the results. For an example, you can see the QRNG sample in the samples gallery in Azure Portal.
I am new to Apache Camel.
I need to split a file line by line and to do some operation on each lines.
At the end I need a footer line with information from previous lines (number of lines and sum of the values of a column)
My understanding is that I should be using an aggregation strategy, so I tried something like that:
.split(body().tokenize("\r\n|\n"), sumAggregationStrategy)
.process("fileProcessor")
In my aggregation strategy I just set two headers with the incremented values:
newExchange.getIn().setHeader("sum", sum);
newExchange.getIn().setHeader("numberOfLines", numberOfLines);
And in the processor I try to access those headers:
int sum = inMessage.getIn().getHeader("sum", Integer.class);
int numberOfLines = inMessage.getIn().getHeader("numberOfLines", Integer.class);
There are two problems.
First of all the aggregation strategy seem to be called after the first iteration of the processor.
Second, my headers don't exist in the processors, so I can't access the information I need when I am at the last line of the file. The headers do exist in the oldExchange of the aggregators though.
I think I can still do it, but I would have to create a new processor just for the purpose of making the last line of the file.
Is there something I'm missing with the aggregation strategies ? Is there a better way to do this ?
An aggregator will be called for every iteration of the split. This is how they are supposed to work.
The reason you don't see the headers within the processor is, headers live and die with the message and not visible outside. You need to set the 'sum' and 'numberOfLines' as exchange properties instead. Because every iteration within a split results in an exchange, you need get the property from old exchange and set them again in the new exchange to pass them to subsequent components in the route.
This is how you could do,
AggregationStrategy:
public class SumAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
long sum = 0;
long numberOfLines = 0;
if(oldExchange != null) {
sum = (Long) oldExchange.getProperty("sum");
numberOfLines = oldExchange.getProperty("numberOfLines ");
}
sum = sum + ((Line)newExchange.getIn().getBody()).getColumnValue();
numberOfLines ++;
newExchange.setProperty("sum", sum);
newExchange.setProperty("numberOfLines",numberOfLines);
oldExchange.setProperty("CamelSplitComplete", newExchange.getProperty("CamelSplitComplete")); //This is for the completion predicate
return newExchange;
}
}
Route:
.split(body().tokenize("\r\n|\n"),sumAggregationStrategy)
.completionPredicate(simple("${exchangeProperty.CamelSplitComplete} == true"))
.process("fileProcessor").to("file:your_file_name?fileExist=Append");
Processor:
public class FileProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
long sum = exchange.getProperty("sum");
long numberOfLines = exchange.getProperty("numberOfLines");
String footer = "Your Footer String";
exchange.getIn().setBody(footer);
}
}
Using custom aggregator like Srini suggested is a good idea. It might also support streaming large files better.
However if you want to keep things simple and avoid split and aggregation you could just use .tokenize("\r\n|\n") and convertBodyTo(List.class) to convert the string to a list of strings.
from("direct:addFooter")
.routeId("addFooter")
.setBody().tokenize("\r\n|\n")
.convertBodyTo(List.class)
.process(exchange -> {
List<String> rows = exchange.getMessage().getBody(List.class);
int sum = 0;
for (int i = 0; i < rows.size(); i++) {
sum += Integer.parseInt(rows.get(i));
}
int numberOfLines = rows.size();
exchange.getMessage().setHeader("numberOfLines", numberOfLines);
exchange.getMessage().setHeader("sum", sum);
})
// Write data to file using file or stream component
// you could also use Velocity, FreeMarker or Mustache templates to format the
// result before writing it to file.
;
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
int x = 20;
String choice = "";
while(x!=0) {
System.out.println("What would you like to do? Enter help for commands.");
choice = userInput.next().toLowerCase();
if(choice.equals("go right")) method();
if(choice.equals("go left")) method();
if(choice.equals("go forwards")) method();
if(choice.equals("go backwards")) method();
if(choice.equals("help")) System.out.println("I can print!");
x--;
System.out.println("Value of x: " + x);
}
}
The code above seems to run twice, x is reduced by two before the scanner asks for user input again.
public void method(){
System.out.println("methoding");
}
Additionally, the method doesn't run when called from an if statement but the print statement will.
Your method isn't being called because userInput.next() will only return the next word (ie. until there's a space). You should look into .nextLine() or .useDelimiter() to change this behaviour and return an entire line.
This also explains why x decreases twice -- if you type "go right", that counts as two separate .next()s.
You must add static to method, because now it's an instance method and can't be called from a static function like main.
Don't check x != 0. It's possible it works, but in a complicated loop, where x can reduce more than one time, it may pass 0, go into negatives and never end the loop. Check x > 0 instead.
Use a for loop instead while, if you need to increment/decrement the loop controlling variable at the end of loop.
I am stuck doing this even though I know it's very simple. Yet, I am getting errors.
What I have:
I have 3 arrays.
1st Array contains objects of UpgradeButton class.
2nd Array contains objects of BuyButtonclass.
3rd Array named newCostlyShops contains Numbers.
BuyButton class and UpgradeButton class, both have a shopCode member which is a number; the number which I'm trying to equate.
What I'm trying to do:
My goal is to first look for BuyButton and UpgradeButton objects in the respective arrays which have shopCodes same as those in newCostlyShops.
After that, I removeChild() that object and splice it out from the array.
My Code:
Array 3:
var newCostlyShops:Array = new Array();
newCostlyShops = Object(root).WorkScreen_mc.returnCostlyShops();
trace(newCostlyShops); // this is tracing out the exact shopCodes I want and is working fine.
Deletion and Splicing codes:
for (looper = 0; looper < upgradeButtonsArray.length; looper++) {
for (var secondLooper: int = 0; secondLooper < newCostlyShops.length; secondLooper++) {
if (upgradeButtonsArray[looper].shopCode == newCostlyShops[secondLooper]) {
trace(looper);
trace(upgradeButtonsArray[looper]);
removeChild(upgradeButtonsArray[looper]);
upgradeButtonsArray.splice(looper, 1);
}
}
}
for (looper = 0; looper < buyButtonsArray.length; looper++) {
for (secondLooper = 0; secondLooper < newCostlyShops.length; secondLooper++) {
if (buyButtonsArray[looper].shopCode == newCostlyShops[secondLooper]) {
trace(looper);
trace(buyButtonsArray[looper]);
removeChild(buyButtonsArray[looper]);
buyButtonsArray.splice(looper, 1);
}
}
}
What's wrong with this Code:
I keep getting error
TypeError: Error #1010: A term is undefined and has no properties.
This error comes only after the 1st time this code is run and not the first time it is run. When I remove the removeChild and splice , this traces out objects that are not null, ever. Even after this whole function is called 100 times, the error is not shown. Only when I removeChild and use splice this occurs.
Is there something wrong with what I'm doing? How to avoid this error? This is throwing the whole program haywire. If there is any other alternative to this method, I'm open to take those methods as well as long as I don't get errors and my goal is reached.
It might sounds funny, but.... try to decrement looper after splicing.
trace(looper);
trace(upgradeButtonsArray[looper]);
removeChild(upgradeButtonsArray[looper]);
upgradeButtonsArray.splice(looper, 1);
looper--;
I think after splicing the array all item's are being shifted and you're skipping next one.
Also, you should get some more information with this error, like which class/line is throwing it. Maybe you need to enable "permit debugging" or something?
Bonus suggestion:
For newCostlyShops use Dictionary instead of Array so you won't have to nest for inside for...
I have a method as follows
public class ClientClass {
public void clientMethod() {
while(true){
doSomethings.....
}
}
}
I am trying to test using mockito. I am able to make the call to clientMethod, but since there is a while(true) inside clientMethod, the call never returns and I never reach to my assert statements which (of course) occur after clientMethod() invocation.
Is there a way to stop the loop after one loop iteration from my test case?
Technicaly you can't break the infinite loop in test without throwing an exception from inside it. If there is something inside the loop you can mock, then it may produce an exception for you.
When you're finding yourself in situation like this, when awkward workarounds are necessary for testing, then it's time to stop and think about the design. Non-testable code is generaly ill-maintainable and not very self-explanatory. So my advice would be to get rid of infinite loop and introduce an appropriate loop condition. After all, no application will live forever.
If you're still convinced that endless loop is the best way to go here, then you can perform a slight decomposition to make things more testable:
public class ClientClass {
// call me in production code
public void clientMethod() {
while(true){
doSomethings();
}
}
// call me in tests
void doSomethings(){
// loop logic
}
}
This was a source of a little frustration to me... because I like to start off the most sophisticated of GUI apps with a console handler.
The language I'm using here is Groovy, which is a sort of marvellous extension of Java, and which can be sort of mixed in with plain old Java.
class ConsoleHandler {
def loopCount = 0
def maxLoopCount = 100000
void loop() {
while( ! endConditionMet() ){
// ... do something
}
}
boolean endConditionMet() {
loopCount++
loopCount > maxLoopCount // NB no "return" needed!
}
static void main( args ) {
new ConsoleHandler().loop()
}
}
... in a testing class (also in Groovy) you can then go
import org.junit.contrib.java.lang.system.SystemOutRule
import org.junit.contrib.java.lang.system.
TextFromStandardInputStream.emptyStandardInputStream
import static org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import static org.mockito.Mockito.*
class XXTests {
#Rule
public SystemOutRule systemOutRule = new SystemOutRule().enableLog()
#Rule
public TextFromStandardInputStream systemInMock = emptyStandardInputStream()
ConsoleHandler spyConsoleHandler = spy(new ConsoleHandler())
#Test
void readInShouldFollowedByAnother() {
spyConsoleHandler.setMaxLoopCount 10
systemInMock.provideLines( 'blah', 'boggle')
spyConsoleHandler.loop()
assertThat( systemOutRule.getLog() ).containsIgnoringCase( 'blah' )
assertThat( systemOutRule.getLog() ).containsIgnoringCase( 'boggle' )
The beautiful thing that's happening here is that simply by declaring maxLoopCount the language automatically creates two methods: getMaxLoopCount and setMaxLoopCount (and you don't even have to bother with brackets).
Of course the next test would be "loop must exit if a user enters Q" or whatever... but the point about TDD is that you want this to FAIL initially!
The above can be replicated using plain old Java, if you must: you have to create your own setXXX method of course.
I got stuck in this because I was calling same method from inside the method by mistake.
public OrderEntity createNewOrder(NewDepositRequest request, String userId) {
return createNewOrder(request, userId);
}