Commit 7377e94b authored by Ayres, Andrew's avatar Ayres, Andrew
Browse files

formatting, figures, added objectives

parent b9023af3
Loading
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -4,6 +4,25 @@ teaching: 10
exercises: 0
---

::::::::::::::::::::::::::::::::::::::: objectives

- Understand the purpose of the NOVA tutorial and its goals.
- Explain the roles of NDIP and NOVA in neutron data analysis.
- Identify the core NOVA libraries and their functionalities.
- Describe the high-level architecture of a NOVA application interacting with NDIP.

::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::: questions

- What is the Neutron Data Interpretation Platform (NDIP)?
- What is NOVA, and how does it simplify NDIP application development?
- What are the key components of NOVA, and what problems do they solve?
- How do NOVA libraries interact with the NDIP platform?
- What will I be able to do after completing this tutorial?

::::::::::::::::::::::::::::::::::::::::::::::::::

# 1. Introduction to NOVA and NDIP

Welcome to the NOVA tutorial! This guide will walk you through the process of building interactive tools for **neutron analysis** using the NOVA platform. You will learn how to create a web application that leverages the NOVA libraries to simplify interaction with the Neutron Data Interpretation Platform (NDIP).
+17 −0
Original line number Diff line number Diff line
@@ -4,6 +4,23 @@ teaching: 10
exercises: 3
---

::::::::::::::::::::::::::::::::::::::: objectives

- Clone the NOVA template application using `copier`.
- Understand the basic project structure created by the template.
- Identify key files in the project (e.g., `pyproject.toml`).
- Install project dependencies using `poetry`.

::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::: questions

- How do I quickly set up a starting point for a NOVA project?
- What files and directories are included in the NOVA template application?
- How does `poetry` manage project dependencies and virtual environments?

::::::::::::::::::::::::::::::::::::::::::::::::::

# 2. Getting Started with a Template Application

As mentioned in the introduction, all code examples in this tutorial are based on a template application. In this episode, we will create this starting point by cloning a template using the `copier` library. This template provides a basic project structure and pre-configured files that will help us get started quickly with our NOVA project, saving us from setting up everything from scratch.
+19 −0
Original line number Diff line number Diff line
@@ -4,6 +4,25 @@ teaching: 10
exercises: 3
---

::::::::::::::::::::::::::::::::::::::: objectives

- Explain the purpose of the `Nova`, `Tool`, and `Parameters` classes in `nova-galaxy`.
- Describe the basic workflow for running an NDIP tool using `nova-galaxy`.
- Connect to NDIP using the `Nova` class.
- Define an NDIP tool and set its parameters using the `Tool` and `Parameters` classes.
- Run the tool and create a datastore.

::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::: questions

- How can I interact with the NDIP platform programmatically from Python?
- What is the `nova-galaxy` library, and how does it simplify NDIP operations?
- How do I define an NDIP tool and specify its input parameters using `nova-galaxy`?
- Where can I find information about what NDIP tool to use and parameters to set?

::::::::::::::::::::::::::::::::::::::::::::::::::

# Using NDIP for Backend Computations
In this section, we will start using the `nova-galaxy` library to interact with the NDIP platform and run a neutron analysis tool.  First, ensure you have set your `GALAXY_URL` and `GALAXY_API_KEY` as environment variables, as explained in the notes at the end of this episode.  We also need to add `nova-galaxy` as a project dependency.

+36 −7
Original line number Diff line number Diff line
@@ -4,6 +4,27 @@ teaching: 10
exercises: 0
---

::::::::::::::::::::::::::::::::::::::: objectives

- Define the Model-View-ViewModel (MVVM) design pattern and its benefits.
- Explain the responsibilities of each component in the MVVM pattern (Model, View, ViewModel).
- Describe the role of data binding in MVVM and how it enables reactive UIs.
- Explain the purpose of the `nova-mvvm` library and its key components (`BindingInterface`, `TrameBinding`, `Communicator`, `new_bind`).
- Introduce Pydantic for data modeling and validation within the MVVM pattern.
- Understand how to implement MVVM using `nova-mvvm` and Pydantic in a NOVA application.

::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::: questions

- What is the Model-View-ViewModel (MVVM) design pattern, and why is it useful for UI development?
- What are the roles and responsibilities of the Model, View, and ViewModel in the MVVM pattern?
- How does data binding work in MVVM, and why is it important?
- How does the `nova-mvvm` library simplify the implementation of the MVVM pattern in NOVA applications?
- What is Pydantic, and how can it be used for data modeling and validation in the context of MVVM?

::::::::::::::::::::::::::::::::::::::::::::::::::

# 4. User Interface Best Practices: The MVVM Design Pattern

In this section, we will introduce the Model-View-ViewModel (MVVM) design pattern, a powerful architectural approach for structuring applications, particularly those with user interfaces. We\'ll explore the core principles of MVVM, the roles of each component, and how the NOVA framework simplifies its implementation, making your code more organized, testable, and maintainable.
@@ -16,8 +37,9 @@ Before diving into MVVM, it\'s helpful to understand what a *design pattern* is

MVVM is an architectural design pattern specifically designed for applications with user interfaces (UIs). It aims to separate the UI (the View) from the underlying data and logic (the Model) by introducing an intermediary component called the ViewModel. This separation makes the application more maintainable, testable, and easier to evolve.

The MVVM pattern consists of three core components:
![](fig/mvvm.png)

The MVVM pattern consists of three core components:
*   **Model:** The Model represents the *data* and the *business logic* of the application. It\'s responsible for:
    *   Data storage (e.g., reading from and writing to a database, a file, or an API).
    *   Data validation (ensuring the data is in a valid state).
@@ -41,7 +63,7 @@ The MVVM pattern consists of three core components:
    *   Handling user actions from the View. This might involve validating user input, updating the Model, or triggering other actions in the application.
    *   Exposing data and commands to the View through *data binding*.

    The ViewModel is *UI-specific*. It knows about the View and the data that the View needs, but it doesn\'t know about the specific UI elements that are used to display the data. It also orchestrates the interaction between the View and the Model.
    The ViewModel knows about the View and the data that the View needs, but it doesn\'t know about the specific UI elements that are used to display the data. It also orchestrates the interaction between the View and the Model.

    *The ViewModel is where we\'ll use `nova-mvvm` to create bindings between the ViewModel and the View, enabling the reactive updates.*

@@ -193,9 +215,8 @@ poetry run app

You should see `Fractal tool finished successfully.` printed to the console, although we have not created a UI yet.

## Exercises

1.  **Trigger Pydantic Validation Error (Programmatic):**
:::::::::::::::::::::::::::::::::::::::  challenge
**Trigger Pydantic Validation Error (Programmatic)**
    *   In `FractalViewModel` in `src/nova_tutorial/view_models/fractal_view_model.py`, modify the `update_fractal_programmatically` function from the previous exercise to use an *invalid* fractal type:
        ```python
        def update_fractal_programmatically(new_type: str):
@@ -211,12 +232,18 @@ You should see `Fractal tool finished successfully.` printed to the console, alt
        *   The "Current fractal type (after attempt):" is still "mandelbrot" indicating the invalid update was rejected.
        *   The "Current message:" now contains a "Validation Error" message from Pydantic.

2.  **Inspect ViewModel State:**
::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::  challenge
**Inspect ViewModel State**
    *   In `src/nova_tutorial/view_models/fractal_view_model.py`, add `print` statements within the `FractalViewModel.__init__` method to print the initial values of `self._fractal_type`, `self._job_status`, and `self._message`.
    *   Run the application (`poetry run app`). Observe the output in the console. Verify that the initial values are printed as expected.
    *   Now, modify the `FractalViewModel.__init__` method to change the initial value of `self._message` to "Application starting...". Run the application again and confirm that the printed initial message has changed.

3.  **Programmatic State Update and Binding:**
::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::  challenge
**Programmatic State Update and Binding:**
    *   In `FractalViewModel` in `src/nova_tutorial/view_models/fractal_view_model.py`, after the line `self.fractal_type_bind = binding.new_bind(...)` in `__init__`, add the following lines:
        ```python
        print("Initial fractal type:", self._fractal_type) # Print initial value
@@ -233,6 +260,8 @@ You should see `Fractal tool finished successfully.` printed to the console, alt
        *   The message "Fractal type updated programmatically to: julia" is printed.
        *   The final fractal type (after programmatic update) is printed as "julia".

::::::::::::::::::::::::::::::::::::::::::::::::::

## References

*   **Nova Documentation**: https://nova-application-development.readthedocs.io/en/latest/
+37 −4
Original line number Diff line number Diff line
@@ -4,6 +4,30 @@ teaching: 20
exercises: 3
---

::::::::::::::::::::::::::::::::::::::: objectives

- Explain the purpose of Trame as a UI framework.
- Describe how `nova-trame` simplifies Trame development in NOVA applications.
- Identify key features and benefits of using Trame.
- Use `nova-trame` components to build a basic user interface.
- Incorporate common Vuetify components into a Trame application.
- Explore the Vuetify component library and identify components suitable for scientific applications.
- Add custom UI components, and tailor their appearance with attributes.

::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::: questions

- What is Trame, and why should I use it for building UIs in NOVA?
- How does `nova-trame` make Trame development easier?
- What are the key advantages of using a declarative UI approach with Trame?
- How can I create a basic UI layout using `nova-trame` components?
- How can I add common Vuetify components (e.g., `VTextField`, `VCheckbox`, `VSlider`) to my Trame application?
- How can I customize the appearance of Vuetify components?
- Where can I find more information about available Vuetify components?

::::::::::::::::::::::::::::::::::::::::::::::::::

# 5. Web-based User Interface Development with Trame

In this section, we will dive into Trame and the `nova-trame` library to build interactive web-based user interfaces for our NOVA applications. We\'ll explore how `nova-trame` simplifies UI development within the NOVA ecosystem and how to use common layout components.
@@ -165,11 +189,20 @@ poetry run start

You should now see the simple UI. When you click the "Sample Tab 1" and "Sample Tab 2" tabs, you should now see the updated content with the new UI components.

## Exercises
:::::::::::::::::::::::::::::::::::::::  challenge
**Explore the `InputField` Component** 
Modify the `InputField` component in `SampleTab1` to automatically retrieve the label, hint, and validation rules from a Pydantic model field. Create a simple Pydantic model with a `username` field with a `title`, `description`, and `min_length` constraint.
::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::  challenge
**Create a Complex Layout**
Combine `GridLayout`, `VBoxLayout`, and `HBoxLayout` components to create a more complex UI layout in `SampleTab2`. Try creating a layout with a header, a sidebar, and a main content area.
::::::::::::::::::::::::::::::::::::::::::::::::::

1.  **Explore the `InputField` Component:** Modify the `InputField` component in `SampleTab1` to automatically retrieve the label, hint, and validation rules from a Pydantic model field. Create a simple Pydantic model with a `username` field with a `title`, `description`, and `min_length` constraint.
2.  **Create a Complex Layout:** Combine `GridLayout`, `VBoxLayout`, and `HBoxLayout` components to create a more complex UI layout in `SampleTab2`. Try creating a layout with a header, a sidebar, and a main content area.
3.  **Customize Component Appearance:** Experiment with customizing the appearance of the Vuetify components using the various props and styles available. Try changing the color, size, font, and other visual attributes of the components. Refer to Vuetify\'s component documentation for details.
:::::::::::::::::::::::::::::::::::::::  challenge
**Customize Component Appearance** 
Experiment with customizing the appearance of the Vuetify components using the various props and styles available. Try changing the color, size, font, and other visual attributes of the components. Refer to Vuetify\'s component documentation for details.
::::::::::::::::::::::::::::::::::::::::::::::::::

## References

Loading