JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, we can help you do it. What have you got so far?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That sounds like an absolutely standard little shop accounting system. It would be madness to pay for a custom application development and its ongoing support rather than simply deploy a standard supported off-the-shelf solution.

Here's the first example I found in a quick Google: https://www.manager.io
(Please note I know absolutely zero about that particular offering, it's just one example from a vast list of such offerings, and its free for a single user.) Are you going to compete with that?
Even if there is something genuinely unique about this particualr requirement I doubt that it would need to be developed in a high-end complex programming language. For data entry and some reports you just need a popular database.

If you really want to offer something in this case maybe you should offer to capture and document his requirements, and survey the market to produce a short list of 3 products that woud suit him. Without knowing where you are I can't comment on fees - daily rates vary beyond belief between different countries and even metropolitan/rural environments.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Without any kind of spec etc it's hard to understand what that code is trying to do, but it looks to me like the private method is going into an infinite recursion (?). If you are adding new members at the head then there's there's no recursion involved.
To me it looks like you are trying to write too much code too soon.

There are two things you can do to fix your development process..

  1. Write pseudo code (like my previous post) and test it in pen-and-paper simulation to get the logic right before writing any Java
  2. Test early, test often. Eg Don't attempt to test is-a-subset methods before confirming that you are creating sets/lists properly in the first case. Your first three pieces of code should be:
    define the node class's members/constructor
    a print method that prints a list of nodes
    a method to add nodes to a list
    ... that's the minimum that you can test, but test and fix that before trying to build more code on top. Then go one step at a time, eg don't try to develop a method that uses isMember until you have tested isMember
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

subSet method is way off - contains code that is not just unneccesary but actually prevents it working - it's really simple given what you already have done, but you have made it too complicated.

s2 is a subset of s1 if

for each element in s2  
    the element is a member of s1 

or, fleshing that out a bit..

    for each element in s2  // use an enhanced for loop syntax
       if (! the element is a member of s1)  // you have a method to do this
         return false
    return true
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

A small point:
line 8 you return in the if construct, so the else and its associated brackets are redundant. This is a very common pattern (it's called a guard )...

myFunction(params) {
    if (there's something wrong with the parameters) 
          return errorvalue;

    // no need for an else here, just get on with it!

    do rest of function
}
AssertNull commented: Good point +7
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Unlike the other solutions this is guaranteed time complexity On, (additional) memory zero.

        int count = a.length; 
        for (int i = 0; i < a.length; i++) {
            if (a[i] == 0) {
                count = 0;
            } else {
                a[i] = ++ count;
            }
        }
        count = a.length;
        for (int i = a.length -1; i >=0; i--) {
            if (a[i] == 0) {
                count = 0;
            } else {
                count ++;
                if (a[i] > count) a[i] = count;
            }
        }
Gribouillis commented: very nice +14
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The surfing is still a nested loop potentially with On^2 (depending on how many zeros there are). Similarly Adam and Danis solution is also potentially On^2

You can make one pass ascending and set each element to its distance from the previous zero, then a second pass descending overwriting any element whose distance from the previous zero is lower. Guaranteed On. I'll post code in a minute

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Some basics:
Everything you use in Java must have been declared. You try to use a variable employee but you have not defined it anywhere.
Spelling, including upper/lower case must be exactly correct... print1n is not the same as println
Punctuation in Java has to exactly correct all the time, so UtilnumFormat is not the same as Util.numFormat. Similarly , is not the same as .
Every open bracket has to have a matching close bracket. Your code has 3 open brackets bit only 2 close brackets, so obviously they cannot match.

The reason Java is so absolutely picky is that it's quicker and cheaper to find and fix errors at compile time than at run time. Java will reject the slightest error in your program just as soon as it sees it, and that takes some getting used to. But it's for your own good. Most of your errors are just careless spelling and punctuation, so they are easy to fix.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

i don't want to make an entire class just for comparing those strings i need to include this in a single class within my project..

It's a common beginner mistake to avoid defining a small class because it seems somehow too complicated. Just look at the Java API to see how common it is to define a class because that makes the code overall simpler. Remember also you can define a class inside another class, especially if it's only going to be used in the outer class.
Anyway, it looks like you have this under control now, so I'll drop out unless you hit a new snag.

in other sites they kicked me already from the begginning when i asked my question

Here at DW we pride ourselves on being beginner-friendly, and taking the time to discuss ideas. All we ask is that you at least match the effort we are putting in - and you certainly have done that.
Tell your friends!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

i get this error...
java.lang.StringIndexOutOfBoundsException:
String index out of range: 5 (in java.lang.String)

That's a start. Almost certainly an incorrect parameter in a call to String's substring method. Now if you look down the stack dump you will find 1 or 2 lines below that the line number in your code where the String method was called, and that's the line you need to look at.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

This is a really interesting challenge! To cope with repeated consecutive chars I think you have to break each string up into blocks of repeated (1 or more) chars and compare those (the block from str2 must be the same char and as long or longer than the block from str1).
I tried this using loops and it seems to work (?). If you agree it works then maybe it will confirm some ideas towards a recursive solution. (?)

So first I created a small immutable class to define a block of a repeated characters. It has a factory static method to create a block from an input String starting at a specified index, and a method to test if one block is the same char and at least as long.

class RepeatedChar {

    final char c;
    final int length;

    public RepeatedChar(char c, int length) {
        this.c = c;
        this.length = length;
    }

    public boolean contains(RepeatedChar rc1) {
        return c == rc1.c && length >= rc1.length;
    }

    public static RepeatedChar from(String s, int startIndex) {
        char c = s.charAt(startIndex);
        int length = 1;
        for (int i = startIndex + 1; i < s.length(); i++) {
            if (s.charAt(i) != c) break;
            length++;
        }
        return new RepeatedChar(c, length);
    }
}

Now using that its easy to loop along the two strings getting the blocks and comparing them

    boolean isDup(String str1, String str2) {
        int i1 = 0, i2 = 0;
        while (i1 < str1.length() && i2 < str2.length()) {
            RepeatedChar …
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

but i get outOfBounds error

When you get an exception ALWAYS post th ecomplete message and the line where it was thrown. Knowing the exact line, and the index value, will make it easy to see what the problem is.

and a tiny point, but it always bugs me to see it...
if (stringChar(s, t, 0, 0)==true)
stringChar(s, t, 0, 0) returns true or false.
true == true is true
false == true is false
ie adding == true to a boolean does exactly nothing execpt clutter/confuse the code.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I'm having trouble coming up with a way to print the max and this line "The longest hailstone sequence starting 7 with a number up to has length____." for the output.

You don't explain exactly where you are stuck, but all you need is something like

for i = 1 .. 7   (pseudocode)
       length = hailstone_Sequence (i)
       keep note of largest length found so far
print "The longest hailstone sequence starting with a number up to has 7 length " + largest length
rproffitt commented: That's a start. +11
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Jacob
You posted this before. You were referred to some good advice. You chose to ignore it and re-post.
I'm closing this thread. Go back to your first thread and show some effort if you want help.
JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I need codes for issue and edit in library management systems

No you don't.
You need to learn php so you can code it yourself. It's what we call "education".
Show what you have done so far, and someone will help you from there.

diafol commented: Very restrained :) +15
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Here's an outline of how something like this can be structured... it contains the ideas you need. Once again - you were asked to use List, not arrays.

class Library { // top=level class, holds everything else, has search methods

   pubic static void main( …

   List<Author> authors = new LinkedList<>();

   void addAuthor(Author a) { …
   List<Author> getAuthors() { …

   List<Book> searchByGenderAndPrice(Gender g, double maxPrice) {
       for (Author a : getAuthors()) {
            if (a.get Gender == etc
            for (Book b: a.getBooks) {
                 if (b.getPrice <= …
                     add this book to the results list
      …            
}

class Author {
    String name, Gender …
    List<Book> books = new LinkedList<>();

    Author(Library lib, String name … ) {
        …
        lib.addAuthor(this);   //  maintain list of all Authors in Library

    void addBook(Book b)  {
    List<Book> getBooks() { …

}

class Book {

    Author author;
    String title, double price etc

    Book(Author a, String title …
         a.addBook(this);  // maintain list of all Books for this Author
         …

}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No need for an array, just read each line from the file, calculate the price x num tickets, add that to a total that you initialise before starting to read the file,

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK, well, I hope you're right. It's tragic that such a valuable service to our future IT professionals is subject to G's whim, but "Where does a 1 ton gorilla sit? Anywhere it wants".
I don't have the skill set you're looking for Dazah, but you have best wishes.
J

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No, I would (humbly) suggest that your time should go on SEO and marketing to drive DaniWeb traffic in general. That would be refected in the kinds of posts you are personally making here - ie you would be discussing SEO and marketing ideas rather than code features.
J
(ps please do not think I am just criticising for the fun of being a troll. I have loved what I have been able to do for others via DaniWeb over the years, and I think it's tragic that this is drying up. For me it's the only priority, and for you too I would imagine: no Daniweb -> no Dazah.)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Dani. Please. For the sake of all of us who love and contribute to DaniWeb, please stop fiddling about with techy black holes and put 100% of your time into saving DaniWeb. DW is the one and only flagship demo for Dazah. Without a thriving living growing example Dazah will be an impossible sell.
Please. Fewer posts about code, more posts about SEO and marketing.
Fous, focus, focus on what really matters.
JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi D2 - hadn't noticed that it was you! :) JC

Sketching out a GUI is a good way to understand the requirements etc, but it's NOT the place to start actual development.

This is an OO exercise, so start with the objects. Look for the important nouns in the problem description - for example Restaurant, Order, Baker, Cashier, Pizza, SIze, Topping, Crust... (maybe you don't need those exact classes, just see how it works out when you add the members and method signatures).
Then hard code a couple of test cases and get all the logic working.

Then design and code the data file processing, which will incidentally give your logic a pretty good test. Think of this as an alternative "user interface" for your classes - so you have one set of classes that represent everything about the restaurant, and two separate ways to use them, one from file , one from GUI.
...
Then and only then create a GUI that uses the functionality that you jave already created and tested. (You may want to add a few more methods to your classes specifically to support the GUI, but these will become obvious when you start coding the GUI.)

When you do, finally, get round to coding the GUI you will find excellent examples and explanations for working with radio buttons etc in the usual Oracle Java Tutorials

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK everybody. This is getting too heated. I'm closing this thread.
JC

Reverend Jim commented: My guess would be Troll. +14
ddanbe commented: MY guess: bitten by a trump mosquito +15
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Oh Richard, don't blame me or Rev Jim. You made a post with 3 points; the first was simply wrong, the second was critical while being unhelpful, and the third was irrelevant at best, downright wrong in this context. After two very experienced people pointed out your mistakes you responded by digging yourself in deeper. It's time to let this go.
JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Maybe you need to work on your Google technique.
I Googled ACH - NACHA payment C# for 38,600 relevant hits.
On the very first page I found a GitHub project: C# library for the NACHA ACH input file structure plus 4 more hits with actual solutions.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes... and... ?

Either contribute something, or ask a proper question.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster
  1. y = x - (1+1) is NOT the same as y = x - 1 + 1 You should learn about operator precedence and L-R execution before criticising
  2. Where exactly do you suppose OP should check for division by zero? That code does not have a single example of division with a variable as its divisor. They are all non-zero constants.
  3. "totally wrong way to go" without suggesting a better way is unhelpful at best.

Peter_36 : I think you can safely ignore Richard-36's nonsense.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Every rule has its exceptions, and this is one. It's very common that you end up with a bag full of assorted utility methods that are low-level things used in various different parts of your system. A literal interpretation of SOLID says you should put each one in a different class, but all that achieves is extra clutter in your name spaces.
Although I am a total believer in SOLID, I still think it's OK to have a class that holds miscellaneous utility methods that belong together because of some similarity of use and do not belong anywhere else.
SOLID exists for one reason only - to make code easier to maintain. The question to ask youself is "by deviating from the strict defintion of SOLID am I improving or harming the maintainability of my code?".

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Did you notice the pinned Programming thread "Read this before posting a question"? It's there for a reason
https://www.daniweb.com/programming/threads/435023/read-this-before-posting-a-question

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

When thinking about how many classes, consider cohesion and coupling (Google it).
The idea is that one class does one thing and contains just enough to do that thing, nothing more.
So a Filter holds filter data and knows how to filter a data object to create new data object.
A Menu knows how to interact with the user and call different functions depending in user input. You could have have multiple Menu classes - one for a command line, one for a GUI, one for a webserver, but they can all use the same Filter class. That's how you get re-use.

You may see that as more complicated, but what happens in reality is that you get multiple classes, each of which does just what it does and interacts only with the public members of any other classes. That makes it really easy to understand the overall division oof responsibility, and easy to understand the implementation of each class in isolation. It's all about architecture

As for instantiating outside main, I can't comment on good C++ practice, but in OO in genreal this is a non-issue. When the logic of your application requires you the create a new instance of something you call the appropriate constructor. To minimise coupling you create/use/destroy instances in the smallest scope/lifetime that makes sense. Doing it in main is about the longest possible lifetime, and potentially shares over a whole-program scope, so it's typically a bad idea.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I agree with assertnull re naming. In fact I'm obsessive about it. Not only does it manage the readability of the code, but good naming makes mistakes jump out at you.

I would change the class names to Filter, Data, and FilteredData

Names OK, but maybe filtered data is still just data, so maybe theRawData and theFilteredData should be instances of the same class Data ? In fact, looking at the limited info we have I wonder if Filter is-a-kind-of Data, and should therefore be a subclass???

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

would it not take away from the concept of encapsulation as it would result in having a class with members which are other classes objects?

Absolutely not. It's rare to find a class that does NOT have members that are objects of other classes (Car has Engine, Transmission. Employee has a Job. etc). What's important is that the containing class doesn't get involved with the internals of the members (and vice-versa). The containing class simply uses the member's public methods to ask them to perform their individual responsibilities (engine.increaseRevs(), transmission.shiftToGear(2) etc)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

This is difficult, if only because the problem isn't rich enough to require much in the way of OO design or implementation.
Anyway, here's one thought:
We start with picking Objects from the components in the problem defintion (DataSet, Filter), but you also need objects to represent the overall processes that the system performs. Often these Objects represent kinds of users (client requests cash from his account, bank teller validates request and issues cash - account is an obvious object, but also client and teller are candidate objects to manage the process). Other times you use an object that simply represents an instance of the process being performed (CashWithdrawal).
In this case you could have a class "Menu" whose responsibilities are to display itself, get the user's choice, create a Data object (this is delegated to the Data class), create a Filter object (delegated to the Filter class), filter the Data (delegated to the Filter object), and print the result (delegated to the Data object that is created by applying the Filter).
Your main just creates an instance of an Menu, and that does the rest.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I see you failed to test this code, because it doesn't get anywhere near the stated functionality.
If you don't understand why try these test strings:

"This data has one sentence starting with a CAPITAL letter."
"this has none, says James."
"An ellipsis looks like this: ... .
"É is a latin capital letter E acute, Unicode: U+00C9, UTF-8: C3 89."
"What about this one? It has zero periods!"

.., ad that's without getting into what happens if any of the interesting characters are inside a quotation.

Listen: It's good that you are posting and contributing here, but for your own reputation you should be more careful about the quality of what you post.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK. This is pushing the limits of my C++ knowledge (I despise C++ ... should have been strangled at birth) but:
You need B and C each to have their own variables, ie not inherited from A.
I know that for functions you can declare a virtual function in A, and implement it in both B and C which will work exactly as you describe, but as far as I know there's no virtual equivalent for variables. If so you can wrap the variables in accessor methods that are defined virtual in A.

There are probably solutions involving casting pointers to the classes, but that way madness lies.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK, don't worry about your English - we will communicate somehow!

Perhaps you are re-initiasing the array somewhere? Maybe the problem is in info_add? Without all the code it's hard to see.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I also cashed in once to see how it worked. But dividing the reward by the number of posts I made it's clear that the financial motivation was vanishingly close to zero. I say "let it die a peaceful death"

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster
  1. Google Java RSA
  2. Click on any of the tutorial/example links that displays
  3. Use some initiative and do a bit of work before posting another lazy request like this.
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I promise no more question.

Sorry, That's not what I meant. Please do ask questions. It's just that your post didn't ask a question, so nobody knew how to answer it.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yup, definitely not Java. Given the reference to iPhone I'll put my money on Swift. And to be fair, he did say "data matrix barcode" and "2D bar code".

rproffitt commented: Yup they did. Our apps do barcodes, and when 2D, we say QRcode. Will try anyway to help. +11
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You always need to split up the command and it parameters. Don't use special-case code like that, you should split up every command, ie

 new ProcessBuilder(cmd.split(" "));

In summary, the easiest general way to execute a command under OSX from Java is to use something like: (also deals with ~ like you would expect)

   void runCommand(String command) {
        command = command.replaceAll("~", System.getProperty("user.home"));
        try {
            new ProcessBuilder(command.split(" ")).
                    redirectError(ProcessBuilder.Redirect.INHERIT).
                    redirectOutput(ProcessBuilder.Redirect.INHERIT).
                    start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Seriously - you commented out line 13? Are we wasting our time here?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I understand, although all they can see is the generated byte code, not your source.
Even creating an exe won't prevent a determined programmer from reverse-engineering or hacking it, so all you can ever achieve is a good enough deterrent.
You can obfuscate your shipped code to make it very hard to read or understand - it replaces variable names by meaningless random strings, shuffles code around (without changing its results) etc. That's certainly enough to stop any but the most comitted programmer. There are utilities that do it for you - google java obfuscate

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Go to http://www.oracle.com/technetwork/java/javase/downloads/jdk-netbeans-jsp-142931.html and download the JDK/NetBeans bundle for Mac OSX. That's everything you need in one package.
It's a standard Mac disk image installer, coudn't be simpler.

When you get your code running with all the errors displayed you will find that the ~ is a problem. Come back here when you get to that stage and I'll walk you through the fix.

JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

/n has no special meaning. But \n is the new line character. The \ is used to start an "escape sequence" that allows you to enter special codes like the following either as a char or as part of a String:

\b (backspace BS, Unicode \u0008)
\t (horizontal tab HT, Unicode \u0009)
\n (linefeed LF, Unicode \u000a)
\f (form feed FF, Unicode \u000c)
\r (carriage return CR, Unicode \u000d)
\" (double quote ", Unicode \u0022)
\' (single quote ', Unicode \u0027)
\\ (backslash \, Unicode \u005c)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, I did come on strong about obsolete versions of Java, but I'm not going to apologise. There really are hideous exploits for older versions of Java in the wild, and if you don't replace them with a currently-supported version you are definitely at risk.

Anyway....
A clean download/install of the the current JDK and Eclipse versions should run perfectly. You could also try NetBeans, which is my personal preference for Java development.
What OS are you on? Looks like Linux or MacOS from your use of the ~

rproffitt commented: I agree. Nothing wrong with pressing how bad an idea it is to use older versions of Java. +11
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Are you saying that setContentView(R.layout.gridviews) is where you get the NPE? Where is Rdefined. Is it null?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

This really is the easiest way... for example here's all the code to run a ls (list directory contents) command and display the output and any errors.

    ProcessBuilder pb =  new ProcessBuilder("ls");
    pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
    pb.redirectError();
    pb.start(); 

(plus 4 lines if you wrap that in a try/catch/printStackTrace())

You don't need all that
ArrayList<String> commands = new ArrayList<String>( Arrays.asList(cmd.split(" ") ) );
stuff. Just
ProcessBuilder pb = new ProcessBuilder(cmd.split(" "));

Re your latest errors:
Are you using an obsolete version of Java? You should be on Java 8 by now, but the above code just needs Java 7. If you're not on a current Java version then you are danger to yourself and those around you - you are missing years and years of critical security fixes and expose yourself and everyone around you to highly malignant malware.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

First thing is to fix that terrible catch clause.
If/when there is an error you just told Java that you didn't want to know anything about it, and please discard the detailed error message that Java just created for you.
ALWAYS put an e.printStackTrace(); in your catch blocks until/unless you have a good reason to do something else.

Second thing: You read the standard output from your Process, but you ignore its error stream, so you won't see any error messages it generates. Best to read/display that as well.

There's a good chance that these two things will give you the info you need.

Last thing: Runtime.exec was replaced over 10 years ago by ProcessBuilder, which is much more powerful and avoids many problems. You should replace this code with the ProcessBuilder equivalent. Google for details and examples.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You need to write it out such as psuedocode or a flow chart

Well, maybe, but in this case the brief and the required artifacts point clearly to an O.O. methodology. What's required is class diagrams and member details, leading to object definition code. There are no use cases, so it's going to be confusing to start with anything that's flow or logic based.
The brief is very detailed, so OP. should find it much easier than he expects if he just follows the instructions step-by-step.