├── .gitattributes
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .gitlab-ci.yml
├── .vs
├── ProjectSettings.json
└── slnx.sqlite
├── Apps
├── CurrentWeatherAppDemo.mlapp
├── CurrentWeatherAppStart.mlapp
└── WeatherDisplay.mlapp
├── CONTRIBUTING.md
├── FunctionLibrary
├── .gitkeep
├── CheckPythonVersion.mlx
└── helloworld.py
├── Images
├── AddCallbackFromContextMenu.mlx
├── AddCallbackInComponentBrowser.mlx
├── AddFunction.mlx
├── AddMultipleComponentsToApp.mlx
├── AddOnsIcon.png
├── AddProperty.mlx
├── EndIcon.png
├── MouseThoughtBubble.png
├── NatickTempPress.png
├── NatickWind.png
├── OpenInFX.png
├── OpenInMO.png
├── RGBTurkeys.png
├── RunPythonLiveTask.png
├── SeaSurfaceTemps.png
├── TestedWith.json
├── WeatherDashboard.png
├── WeatherStruct.png
└── windTokyo.gif
├── InstructorResources
└── Solutions
│ ├── CheckingTheWeatherSoln.mlx
│ ├── CreateCurrentWeatherAppSoln.mlx
│ └── UsingMATLABwithPythonSoln.mlx
├── LICENSE.md
├── MATLABwithPython.prj
├── MainMenu.mlx
├── README.md
├── README.mlx
├── SECURITY.md
├── Scripts
├── CheckingTheWeather.mlx
├── CreateCurrentWeatherApp.mlx
├── UsingMATLABwithPython.mlx
└── checkcurrentweather.py
├── SoftwareTests
├── CheckTestResults.m
├── CreateBadge.m
├── FunctionTests.m
├── OrigSmokeTests.m
├── PostFiles
│ ├── PostCheckingTheWeather.m
│ ├── PostCheckingTheWeatherSoln.m
│ ├── PostCreateCurrentWeatherApp.m
│ ├── PostCreateCurrentWeatherAppSoln.m
│ ├── PostUsingMATLABwithPython.m
│ └── PostUsingMATLABwithPythonSoln.m
├── PostSmokeTest.m
├── PreFiles
│ ├── PreCheckingTheWeather.m
│ ├── PreCheckingTheWeatherSoln.m
│ ├── PreCreateCurrentWeatherApp.m
│ ├── PreCreateCurrentWeatherAppSoln.m
│ ├── PreUsingMATLABwithPython.m
│ ├── PreUsingMATLABwithPythonSoln.m
│ ├── Response.json
│ └── ResponseOneCall.json
├── Response.json
├── ResponseOneCall.json
├── ResponseOneCallOneLine.json
├── RunAllTests.m
├── SmokeTests.m
├── SolnSmokeTests.m
├── TestResults_R2023a.txt
└── TestResults_R2024a.txt
├── Utilities
├── OldVersions
│ ├── CheckingTheWeatherOld.mlx
│ └── UsingMATLABwithPythonOld.mlx
├── ProjectShutdown.m
├── ProjectStartupApp.m
└── SurveyLinks.mat
└── resources
└── project
├── 2zjcQkVJSJ_AwC9M8R9BTSESRzc
├── QEd0x6jBcKf03RgXQ3y07QAWBCsd.xml
├── QEd0x6jBcKf03RgXQ3y07QAWBCsp.xml
├── _kanDHLwZvrSM1wrb2rL3R-TtpAd.xml
├── _kanDHLwZvrSM1wrb2rL3R-TtpAp.xml
├── b4fK1nwNVcMFfH2HWk_9bHC2cXcd.xml
└── b4fK1nwNVcMFfH2HWk_9bHC2cXcp.xml
├── 6xhH2l9GP9loT6TdFn_Mo65sDHg
├── P8PSrqcBHMbGhqD2r1d9oc0h3TUd.xml
└── P8PSrqcBHMbGhqD2r1d9oc0h3TUp.xml
├── BT5hWoz-UTefONdqForZyI91O8Y
├── -Yp4iI7AkN0RXWsqH_qBv8BSoUsd.xml
├── -Yp4iI7AkN0RXWsqH_qBv8BSoUsp.xml
├── 5wkpcXVsAhrdVuZJuRCjlxSek_Yd.xml
├── 5wkpcXVsAhrdVuZJuRCjlxSek_Yp.xml
├── 897K1ZIAIxWZa69h7rzaFEkJJ1Yd.xml
├── 897K1ZIAIxWZa69h7rzaFEkJJ1Yp.xml
├── LUM1KVG-kpiMYV7i1xDItZmUkVQd.xml
├── LUM1KVG-kpiMYV7i1xDItZmUkVQp.xml
├── SGHsdnqYqyGyYGQP-0wqh6AyERAd.xml
├── SGHsdnqYqyGyYGQP-0wqh6AyERAp.xml
├── TzEa1ML1Hz49sPNQX5JM6EE413Qd.xml
├── TzEa1ML1Hz49sPNQX5JM6EE413Qp.xml
├── Ur1esh7xN9L6aqDUKBE31DKE1Qod.xml
├── Ur1esh7xN9L6aqDUKBE31DKE1Qop.xml
├── VnvWkijFxdp8LV3ck_Qpq9eyOpMd.xml
├── VnvWkijFxdp8LV3ck_Qpq9eyOpMp.xml
├── WNBzWWmVwu8nwCU7p01ZJtQ5j-od.xml
├── WNBzWWmVwu8nwCU7p01ZJtQ5j-op.xml
├── gK0bzvM8fEYFwItc078tqn4EOmId.xml
├── gK0bzvM8fEYFwItc078tqn4EOmIp.xml
├── h026LEbG6ImfsgAII1WcSM9Hnnod.xml
├── h026LEbG6ImfsgAII1WcSM9Hnnop.xml
├── nA_28eBnx5NCFw_vQVWFh5ohqUAd.xml
├── nA_28eBnx5NCFw_vQVWFh5ohqUAp.xml
├── w234j28OzyIgK86-1WWW6oJ1rp4d.xml
├── w234j28OzyIgK86-1WWW6oJ1rp4p.xml
├── xH29tmOwPG1ix8h2YNwMHPQ_-ukd.xml
└── xH29tmOwPG1ix8h2YNwMHPQ_-ukp.xml
├── BjxNC43HIPP8KZwg_cceb68ikkA
├── AHoLGOV6JxAa3mDfXPOye2W3psUd.xml
├── AHoLGOV6JxAa3mDfXPOye2W3psUp.xml
├── NvNsziUvXU2FO5oXU12jeMmASEwd.xml
├── NvNsziUvXU2FO5oXU12jeMmASEwp.xml
├── dxW0rLxFMXm0cpQGCSkWQRi2YRsd.xml
└── dxW0rLxFMXm0cpQGCSkWQRi2YRsp.xml
├── EEtUlUb-dLAdf0KpMVivaUlztwA
├── -upqjogKesBp3DwJRlG6KjrKvd4d.xml
├── -upqjogKesBp3DwJRlG6KjrKvd4p.xml
├── 2vfmNT5dFMoKB5FDZBSr3ouDAL8d.xml
├── 2vfmNT5dFMoKB5FDZBSr3ouDAL8p.xml
├── DxJWFQ6s-5tgLo-3uCpCdq16n-sd.xml
├── DxJWFQ6s-5tgLo-3uCpCdq16n-sp.xml
├── JzO7EW4RnUYzi9OV7qh3x-wX4z8d.xml
├── JzO7EW4RnUYzi9OV7qh3x-wX4z8p.xml
├── Pq7gqYnkFyhKab7XB8O0iwQTIP0d.xml
├── Pq7gqYnkFyhKab7XB8O0iwQTIP0p.xml
├── _8KD0FwxV6biv7mEQTGecP1TTPgd.xml
├── _8KD0FwxV6biv7mEQTGecP1TTPgp.xml
├── cn2Ee7NifKI7ffnw_Fjz5lrC1Qgd.xml
├── cn2Ee7NifKI7ffnw_Fjz5lrC1Qgp.xml
├── dzjyExK2OLpL1YhePZIjY4vjrpsd.xml
├── dzjyExK2OLpL1YhePZIjY4vjrpsp.xml
├── e7wCov_BYJUY6VsFZYx5ab3064gd.xml
├── e7wCov_BYJUY6VsFZYx5ab3064gp.xml
├── ikoU0GqEAVreEIpyvUR8mCIaiqUd.xml
├── ikoU0GqEAVreEIpyvUR8mCIaiqUp.xml
├── lMJoqU1GA86jWAvX6adHL2EbMzMd.xml
├── lMJoqU1GA86jWAvX6adHL2EbMzMp.xml
├── nBednXcpm1PUS8qxyRkFXdab-P4d.xml
└── nBednXcpm1PUS8qxyRkFXdab-P4p.xml
├── HoHDHQ_WvHAAKj5aJOrvrg_vpt8
├── xXlmKuOQ7YT_G1elNhbKQIUqSRMd.xml
└── xXlmKuOQ7YT_G1elNhbKQIUqSRMp.xml
├── KAXfQgCar2Yb8zOxgvf9hdmLP1E
├── jYpi1Pu6k-AfWEJrahCTREe7wz0d.xml
├── jYpi1Pu6k-AfWEJrahCTREe7wz0p.xml
├── xcK8fO1pjra5DR0jot5vrzlBV84d.xml
└── xcK8fO1pjra5DR0jot5vrzlBV84p.xml
├── NjSPEMsIuLUyIpr2u1Js5bVPsOs
├── 2kj09UetkV_lru3gvSPXnY6-nM4d.xml
├── 2kj09UetkV_lru3gvSPXnY6-nM4p.xml
├── KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
├── KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
├── QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
├── QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
├── R1RggVhA72agIvELiuhWPRS8F0Id.xml
├── R1RggVhA72agIvELiuhWPRS8F0Ip.xml
├── aEHSZBIY-yve10yGis12Zr5DLZod.xml
├── aEHSZBIY-yve10yGis12Zr5DLZop.xml
├── j4xwF_j8iFTVayUMfxLgMnTbencd.xml
├── j4xwF_j8iFTVayUMfxLgMnTbencp.xml
├── r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
└── r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
├── Project.xml
├── ZN2RlSIbyWXhOxbxxI4hOawbMD4
├── EyDhXb-HjEIhAYfuSMUxquCH4aYd.xml
├── EyDhXb-HjEIhAYfuSMUxquCH4aYp.xml
├── d1u4eIKNgMuS21WRxXrD0UScuR8d.xml
├── d1u4eIKNgMuS21WRxXrD0UScuR8p.xml
├── gjXMbSOzqQJbg7H7bMF0OVGji80d.xml
├── gjXMbSOzqQJbg7H7bMF0OVGji80p.xml
├── p5HYYVUpTuYgZwnT8QkkzaoJraUd.xml
├── p5HYYVUpTuYgZwnT8QkkzaoJraUp.xml
├── q4FWbcu8zEbneDjWzNwfvfvjQNAd.xml
├── q4FWbcu8zEbneDjWzNwfvfvjQNAp.xml
├── s-04wUzHjOhlMa1CW_zpJwm8iDMd.xml
└── s-04wUzHjOhlMa1CW_zpJwm8iDMp.xml
├── ZdVxxv9BsNz7MGUxtEc6Pq3qh1M
├── IeTljmmsHd59nip38CQ5y5dOQnQd.xml
├── IeTljmmsHd59nip38CQ5y5dOQnQp.xml
├── QOpe-1pctdftDIjwQLRdjOUZW44d.xml
├── QOpe-1pctdftDIjwQLRdjOUZW44p.xml
├── bzMXcEpQelehv3qzHYr9ceCGgIod.xml
├── bzMXcEpQelehv3qzHYr9ceCGgIop.xml
├── hy3T897OVbl4TCaWFBnKRKDU0M8d.xml
└── hy3T897OVbl4TCaWFBnKRKDU0M8p.xml
├── fjRQtWiSIy7hIlj-Kmk87M7s21k
├── NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
└── NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
├── iMwdHOXOBiBXhnA_li8gtEJVTjc
├── RMvf4mEDuznAOqU6SKNmIWErfxgd.xml
├── RMvf4mEDuznAOqU6SKNmIWErfxgp.xml
├── ZTr3GAe6p03ZVs2FdKKE0JsiFMQd.xml
├── ZTr3GAe6p03ZVs2FdKKE0JsiFMQp.xml
├── uIbyU9dPEHKvxjdwx5pD9PDDCZYd.xml
└── uIbyU9dPEHKvxjdwx5pD9PDDCZYp.xml
├── qaw0eS1zuuY1ar9TdPn1GMfrjbQ
├── 2zjcQkVJSJ_AwC9M8R9BTSESRzcd.xml
├── 2zjcQkVJSJ_AwC9M8R9BTSESRzcp.xml
├── BT5hWoz-UTefONdqForZyI91O8Yd.xml
├── BT5hWoz-UTefONdqForZyI91O8Yp.xml
├── BjxNC43HIPP8KZwg_cceb68ikkAd.xml
├── BjxNC43HIPP8KZwg_cceb68ikkAp.xml
├── KocSmEw1PpelhlG7ZNeMUdHVtywd.xml
├── KocSmEw1PpelhlG7ZNeMUdHVtywp.xml
├── QMJD9OLFzxcTTbPOoh-ahQ4zTRUd.xml
├── QMJD9OLFzxcTTbPOoh-ahQ4zTRUp.xml
├── R0IsxKENiOKovWZXASFjrmpbBCYd.xml
├── R0IsxKENiOKovWZXASFjrmpbBCYp.xml
├── ZN2RlSIbyWXhOxbxxI4hOawbMD4d.xml
├── ZN2RlSIbyWXhOxbxxI4hOawbMD4p.xml
├── ZdVxxv9BsNz7MGUxtEc6Pq3qh1Md.xml
├── ZdVxxv9BsNz7MGUxtEc6Pq3qh1Mp.xml
├── iMwdHOXOBiBXhnA_li8gtEJVTjcd.xml
├── iMwdHOXOBiBXhnA_li8gtEJVTjcp.xml
├── rh0jHbNfmojECiiHH7BQHmZTsWkd.xml
├── rh0jHbNfmojECiiHH7BQHmZTsWkp.xml
├── rnpMu7jn2QWt_rQcz8FJ-MxGzVId.xml
├── rnpMu7jn2QWt_rQcz8FJ-MxGzVIp.xml
├── trBOSMFt-ZFz0tI8PrpBhVjGM5Md.xml
└── trBOSMFt-ZFz0tI8PrpBhVjGM5Mp.xml
├── root
├── 6x1BhZX_fLnKpcwqra0qFwv1jIgp.xml
├── 6xhH2l9GP9loT6TdFn_Mo65sDHgp.xml
├── EEtUlUb-dLAdf0KpMVivaUlztwAp.xml
├── GiiBklLgTxteCEmomM8RCvWT0nQd.xml
├── GiiBklLgTxteCEmomM8RCvWT0nQp.xml
├── HoHDHQ_WvHAAKj5aJOrvrg_vpt8p.xml
├── KAXfQgCar2Yb8zOxgvf9hdmLP1Ep.xml
├── NmGqIpAwUJcXFyLjFAGnU9uyN5Yp.xml
├── WZRuNzqc-Db7NcQAZO8Y-R8U9ccp.xml
├── fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
└── qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
├── rootp.xml
├── uuid-0192afd8-7310-46b8-ad07-aacb330fc399.xml
└── uuid-366ca619-578a-4bc0-8012-bfa62d28c37f.xml
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.fig binary
2 | *.mat binary
3 | *.mdl binary diff merge=mlAutoMerge
4 | *.mdlp binary
5 | *.mexa64 binary
6 | *.mexw64 binary
7 | *.mexmaci64 binary
8 | *.mlapp binary linguist-language=MATLAB
9 | *.mldatx binary
10 | *.mlproj binary
11 | *.mlx binary merge=mlAutoMerge linguist-language=MATLAB
12 | *.p binary
13 | *.sfx binary
14 | *.sldd binary
15 | *.slreqx binary merge=mlAutoMerge
16 | *.slmx binary merge=mlAutoMerge
17 | *.sltx binary
18 | *.slxc binary
19 | *.slx binary merge=mlAutoMerge linguist-language=Simulink
20 | *.slxp binary
21 |
22 | ## Other common binary file types
23 | *.docx binary
24 | *.exe binary
25 | *.jpg binary
26 | *.pdf binary
27 | *.png binary
28 | *.xlsx binary
29 |
30 | # Ignore HTML
31 |
32 | *.html linguist-detectable=false
33 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: MATLAB Build
2 |
3 | # Controls when the action will run.
4 | on:
5 | push:
6 | branches: [ release ]
7 | pull_request:
8 | branches: [ release ]
9 | workflow_dispatch:
10 |
11 | # Add permission to write GitHub pages
12 | permissions:
13 | contents: write
14 | pages: write
15 | id-token: write
16 |
17 | jobs:
18 | test:
19 | strategy:
20 | fail-fast: false
21 | matrix:
22 | MATLABVersion: [R2024a,R2024b]
23 | runs-on: ubuntu-latest
24 | steps:
25 | # Checks-out your repository
26 | - uses: actions/checkout@v4
27 |
28 | # Sets up a display server
29 | - name: Start display server
30 | if: ${{ always() }}
31 | run: |
32 | sudo apt-get install xvfb
33 | Xvfb :99 &
34 | echo "DISPLAY=:99" >> $GITHUB_ENV
35 |
36 | # Sets up MATLAB
37 | - name: Setup MATLAB
38 | uses: matlab-actions/setup-matlab@v2
39 | with:
40 | release: ${{ matrix.MATLABVersion }}
41 | products: >
42 | Symbolic_Math_Toolbox
43 | # Simulink Statistics_and_Machine_Learning_Toolbox
44 | # List required products above in the format shown (and uncomment them)
45 | # List of product strings:
46 | # Simulink
47 | # Statistics_and_Machine_Learning_Toolbox
48 | # Simulink_Coder
49 | # Econometrics_Toolbox
50 | # Deep_Learning_Toolbox
51 |
52 |
53 | # Run all the tests
54 | - name: Run SmokeTests
55 | uses: matlab-actions/run-command@v2
56 | with:
57 | command: openProject(pwd); RunAllTests;
58 |
59 | # Upload the test results as artifact
60 | - name: Upload TestResults
61 | if: ${{ always() }}
62 | uses: actions/upload-artifact@v4
63 | with:
64 | name: TestResults_${{ matrix.MATLABVersion }}
65 | path: ./public/*
66 | overwrite: true
67 |
68 | badge:
69 | if: ${{ always() }}
70 | needs: [test]
71 | strategy:
72 | fail-fast: false
73 | runs-on: ubuntu-latest
74 | steps:
75 |
76 | # Checks-out your repository
77 | - uses: actions/checkout@v4
78 |
79 | # Sets up R2023b
80 | - name: Setup MATLAB
81 | uses: matlab-actions/setup-matlab@v2
82 | with:
83 | release: R2024b
84 |
85 | # Download the test results from artifact
86 | - name: Download All TestResults
87 | uses: actions/download-artifact@v4
88 | with:
89 | path: public
90 | pattern: TestResults_*
91 | merge-multiple: true
92 |
93 | # Create the test results badge
94 | - name: Run PostSmokeTest
95 | uses: matlab-actions/run-command@v2
96 | with:
97 | command: openProject(pwd); PostSmokeTest;
98 |
99 | # Deploy reports to GitHub pages
100 | - name: Setup Pages
101 | uses: actions/configure-pages@v5
102 | - name: Upload pages artifact
103 | uses: actions/upload-pages-artifact@v3
104 | with:
105 | path: public
106 | - name: Deploy to GitHub Pages
107 | id: deployment
108 | uses: actions/deploy-pages@v4
109 |
110 | # Commit the JSON for the MATLAB releases badge
111 | - name: Commit changed files
112 | continue-on-error: true
113 | run: |
114 | git config user.name "${{ github.workflow }} by ${{ github.actor }}"
115 | git config user.email "<>"
116 | git pull
117 | git add Images/TestedWith.json
118 | git commit Images/TestedWith.json -m "Update CI badges ${{ github.ref_name }}"
119 | git fetch
120 | git push
121 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # List of untracked files to ignore
2 |
3 | # Autosave files
4 | *.asv
5 | *.m~
6 | *.autosave
7 | *.slx.r*
8 | *.mdl.r*
9 | __pycache__
10 | *.pyc
11 | */*.pyc
12 |
13 | # MATLAB Drive
14 | *.MATLABDriveTag
15 |
16 | # Compiled files
17 | *.mex*
18 | *.p
19 |
20 | # Compressed files
21 | *.zip
22 |
23 | # Packaged app and toolbox files
24 | *.mlappinstall
25 | *.mltbx
26 |
27 | # Deployable archives
28 | *.ctf
29 |
30 | # Generated helpsearch folders
31 | helpsearch*/
32 |
33 | # Defined Simulink cache folder
34 | Utilities/SimulinkCache/*
35 |
36 | # Standard code generation folders
37 | slprj/
38 | sccprj/
39 | codegen/
40 |
41 | # Code generation file
42 | *.eep
43 | *.elf
44 | *.hex
45 | *.bin
46 |
47 | # Cache files
48 | *.slxc
49 |
50 | # Project settings
51 | Utilities/ProjectSettings.mat
52 |
53 | # GitLab page folder
54 | public/
55 |
56 | # Prevent accidentally committing your API key
57 | myAPIkey.txt
58 |
59 | # Live Task Repository
60 | MATLAB-Live-Task-for-Python
61 |
62 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | stages:
2 | # Set up two testing paths
3 | - setup
4 | - test
5 | - deploy
6 | - release
7 |
8 | setup-job:
9 | tags:
10 | - matlab
11 | stage: setup
12 | script:
13 | - cd ..
14 | - if (test-path utilities) { rm -r -force utilities }
15 | - git clone git@insidelabs-git.mathworks.com:modular-curriculum-content/utilities.git
16 | - cd $CI_PROJECT_NAME
17 | allow_failure: false
18 |
19 |
20 | smoke-test:
21 | # Smoke tests should run all the time
22 | tags:
23 | # Add additional tags like (e.g. - arduino) as required
24 | # Make sure that the runner you plan to use matches the tags
25 | - matlab
26 | stage: test
27 | script:
28 | - matlab -batch "openProject(pwd);RunAllTests(true)"
29 | when: always
30 | allow_failure: true
31 | artifacts:
32 | paths:
33 | - public/*
34 | expire_in: 1 years
35 |
36 | pages:
37 | tags:
38 | - matlab
39 | stage: deploy
40 | script:
41 | - echo 'Deploying pages'
42 | artifacts:
43 | paths:
44 | - public
45 |
46 | smoke-test-solution:
47 | tags:
48 | - matlab
49 | stage: release
50 | script:
51 | - matlab -batch "proj = openProject(pwd);
52 | addpath(genpath(proj.RootFolder));
53 | results = runtests(fullfile('InternalFiles','Tests','CI','SolnSmokeTests.m'));
54 | disp(table(results)); assertSuccess(results);"
55 | rules:
56 | # This test should always run when merging to main
57 | # And be available for manual running on any push
58 | - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
59 | when: always
60 | - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
61 | when: manual
62 | allow_failure: true
63 |
64 | file-test:
65 | tags:
66 | - matlab
67 | stage: release
68 | script:
69 | - matlab -batch "proj = openProject(pwd);
70 | addpath(proj.RootFolder+'/InternalFiles/Tests/CI');
71 | results = runtests('OpenCloseFileTest.m');
72 | disp(table(results)); assertSuccess(results);"
73 | rules:
74 | # This test should always run when merging to main
75 | # And be available for manual running on any push
76 | - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
77 | when: always
78 | - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
79 | when: manual
80 | allow_failure: true
81 |
82 | release-testing:
83 | tags:
84 | - matlab
85 | stage: release
86 | script:
87 | - matlab -batch "proj = openProject(pwd);
88 | cd ..;
89 | addpath(genpath(fullfile('utilities','TestingResources')));
90 | runCMTests"
91 | rules:
92 | # This test should always run when merging to main
93 | # And be available for manual running on any push
94 | - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
95 | when: always
96 | - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
97 | when: manual
98 | allow_failure: true
99 |
--------------------------------------------------------------------------------
/.vs/ProjectSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentProjectSetting": null
3 | }
--------------------------------------------------------------------------------
/.vs/slnx.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/.vs/slnx.sqlite
--------------------------------------------------------------------------------
/Apps/CurrentWeatherAppDemo.mlapp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Apps/CurrentWeatherAppDemo.mlapp
--------------------------------------------------------------------------------
/Apps/CurrentWeatherAppStart.mlapp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Apps/CurrentWeatherAppStart.mlapp
--------------------------------------------------------------------------------
/Apps/WeatherDisplay.mlapp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Apps/WeatherDisplay.mlapp
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | >_If you believe you have discovered a security vulnerability, please **do not** open an issue or make a pull request. Follow the instructions in the [SECURITY.md](SECURITY.md) file in this repository._
4 |
5 | Thank you for your interest in contributing to a MathWorks repository! We encourage contributions large and small to this repository.
6 |
7 | **Contributions do not have to be code!** If you see a way to explain things more clearly or a great example of how to use something, please contribute it (or a link to your content). We welcome issues even if you don't code the solution. We also welcome pull requests to resolve issues that we haven't gotten to yet!
8 |
9 | ## How to give feedback
10 | * **Send us an email:** Contact the [MathWorks teaching resources team.](mailto:onlineteaching@mathworks.com)
11 | * **Open an issue:** Start by [creating an issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue) in the repository that you're interested in. That will start a conversation with the maintainer. When you are creating a bug report, please include as many details as possible. Please remember that other people do not have your background or understanding of the issue; make sure you are clear and complete in your description.
12 |
13 | ## How to contribute to the repository
14 | * **Work in your own public fork:** If you choose to make a contribution, you should [fork the repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo). This creates an editable copy on GitHub where you can write, test, and refine your changes. We suggest that you keep your changes small and focused on the issue you submitted.
15 | * **Sign a Contributor License Agreement (CLA):** We require that all outside contributors sign a [CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement) before we can accept your contribution. When you create a pull request (see below), we'll reach out to you if you do not already have one on file. Essentially, the CLA gives us permission to publish your contribution as part of the repository.
16 | * **Make a pull request:** "[Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests)" is a confusing term, but it means exactly what it says: You're requesting that the maintainers of the repository pull your changes in. If you don't have a CLA on file, we'll reach out to you. Your contribution will be reviewed, and we may ask you to revise your pull request based on our feedback. Once everyone is satisfied, we'll merge your pull request into the repository.
17 |
18 | ## Guidelines
19 |
20 | We don't have best practices for writing MATLAB® code, but we do have some recommendations:
21 |
22 | * You should not have any warnings or errors in the [code analyzer report](http://www.mathworks.com/help/matlab/matlab_prog/matlab-code-analyzer-report.html)
23 | * [Loren Shure's blog](https://blogs.mathworks.com/loren) has [great advice on improving your MATLAB code](https://blogs.mathworks.com/loren/category/best-practice/)
24 | * Examples should be written as [live scripts](https://www.mathworks.com/help/matlab/matlab_prog/what-is-a-live-script-or-function.html) or [Simulink® models](https://www.mathworks.com/help/simulink/index.html).
25 | * We adhere to the [CommonMark](https://commonmark.org/) specification where it does not conflict with GitHub rendering. If you edit your Markdown in Visual Studio Code or a similar editor, it uses [markdownlint](https://github.com/DavidAnson/markdownlint) to highlight issues in your Markdown.
26 |
27 | **Again, thanks for contributing, and we look forward to your issues and pull requests!**
28 |
--------------------------------------------------------------------------------
/FunctionLibrary/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/FunctionLibrary/.gitkeep
--------------------------------------------------------------------------------
/FunctionLibrary/CheckPythonVersion.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/FunctionLibrary/CheckPythonVersion.mlx
--------------------------------------------------------------------------------
/FunctionLibrary/helloworld.py:
--------------------------------------------------------------------------------
1 | print("Hello, "+name+"!")
--------------------------------------------------------------------------------
/Images/AddCallbackFromContextMenu.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/AddCallbackFromContextMenu.mlx
--------------------------------------------------------------------------------
/Images/AddCallbackInComponentBrowser.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/AddCallbackInComponentBrowser.mlx
--------------------------------------------------------------------------------
/Images/AddFunction.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/AddFunction.mlx
--------------------------------------------------------------------------------
/Images/AddMultipleComponentsToApp.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/AddMultipleComponentsToApp.mlx
--------------------------------------------------------------------------------
/Images/AddOnsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/AddOnsIcon.png
--------------------------------------------------------------------------------
/Images/AddProperty.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/AddProperty.mlx
--------------------------------------------------------------------------------
/Images/EndIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/EndIcon.png
--------------------------------------------------------------------------------
/Images/MouseThoughtBubble.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/MouseThoughtBubble.png
--------------------------------------------------------------------------------
/Images/NatickTempPress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/NatickTempPress.png
--------------------------------------------------------------------------------
/Images/NatickWind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/NatickWind.png
--------------------------------------------------------------------------------
/Images/OpenInFX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/OpenInFX.png
--------------------------------------------------------------------------------
/Images/OpenInMO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/OpenInMO.png
--------------------------------------------------------------------------------
/Images/RGBTurkeys.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/RGBTurkeys.png
--------------------------------------------------------------------------------
/Images/RunPythonLiveTask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/RunPythonLiveTask.png
--------------------------------------------------------------------------------
/Images/SeaSurfaceTemps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/SeaSurfaceTemps.png
--------------------------------------------------------------------------------
/Images/TestedWith.json:
--------------------------------------------------------------------------------
1 | {"schemaVersion":1,"label":"Test Status","color":"success","message":"R2024a | R2024b"}
2 |
--------------------------------------------------------------------------------
/Images/WeatherDashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/WeatherDashboard.png
--------------------------------------------------------------------------------
/Images/WeatherStruct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/WeatherStruct.png
--------------------------------------------------------------------------------
/Images/windTokyo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Images/windTokyo.gif
--------------------------------------------------------------------------------
/InstructorResources/Solutions/CheckingTheWeatherSoln.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/InstructorResources/Solutions/CheckingTheWeatherSoln.mlx
--------------------------------------------------------------------------------
/InstructorResources/Solutions/CreateCurrentWeatherAppSoln.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/InstructorResources/Solutions/CreateCurrentWeatherAppSoln.mlx
--------------------------------------------------------------------------------
/InstructorResources/Solutions/UsingMATLABwithPythonSoln.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/InstructorResources/Solutions/UsingMATLABwithPythonSoln.mlx
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2024, The MathWorks, Inc.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are
6 | met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the distribution
13 | * Neither the name of the The MathWorks, Inc. nor the names
14 | of its contributors may be used to endorse or promote products derived
15 | from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/MATLABwithPython.prj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/MainMenu.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/MainMenu.mlx
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Programming: A Starter Project Using MATLAB with Python
3 |
4 |
5 | [](https://www.mathworks.com/matlabcentral/fileexchange/116490-programming-a-starter-project-using-matlab-and-python) or [](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python&project=MATLABwithPython.prj&file=README.mlx)
6 |
7 | [](https://MathWorks-Teaching-Resources.github.io/Programming-A-Starter-Project-Using-MATLAB-and-Python)
8 |
9 | **Curriculum Module**
10 |
11 | _Created with R2024a. Compatible with R2024a and later releases._
12 |
13 | # Information
14 |
15 | This curriculum module contains interactive [MATLAB® live scripts](https://www.mathworks.com/products/matlab/live-editor.html) that teach fundamental concepts and basic terminology related to programming computers.
16 |
17 | # Prerequisite Domain Knowledge
18 |
19 | This module assumes familiarity with basic programming concepts such as variables, data types, and functions, structures including arrays and structs, and control flows including if/else as well as how to use them in MATLAB. These ideas are all presented with interactive examples in [Fundamentals of Programming](https://www.mathworks.com/matlabcentral/fileexchange/103225-fundamentals-of-programming), [Programming: Organizing Data](https://www.mathworks.com/matlabcentral/fileexchange/115900-programming-organizing-data), [Programming: Structuring Code](https://www.mathworks.com/matlabcentral/fileexchange/115905-programming-structuring-code).
20 |
21 |
22 | ## Background
23 |
24 | You can use these live scripts as demonstrations in lectures, class activities, or interactive assignments outside class. This module explores interactions between systems by using the OpenWeather API and calling into Python from MATLAB. **Programming: A Starter Project Using MATLAB with Python** covers using the Run Python Code Live Task to run provided Python code, accessing the OpenWeather API to check the weather, extracting useful data from the API call, and using App Designer to create an app with a personalized weather display.
25 |
26 |
27 | The instructions inside the live scripts will guide you through the exercises and activities. Get started with each live script by running it one section at a time. To stop running the script or a section midway (for example, when an animation is in progress), use the
Stop button in the **RUN** section of the **Live Editor** tab in the MATLAB Toolstrip.
28 |
29 | ## Contact Us
30 |
31 | Solutions are available upon instructor request. Contact the [MathWorks teaching resources team](mailto:onlineteaching@mathworks.com) if you would like to request solutions, provide feedback, or if you have a question.
32 |
33 |
34 | ## Prerequisites
35 |
36 | This module assumes familiarity with basic programming concepts such as variables, data types, and functions, structures including arrays and structs, and control flows including if/else as well as how to use them in MATLAB. These ideas are all presented with interactive examples in [Fundamentals of Programming](https://github.com/MathWorks-Teaching-Resources/Fundamentals-of-Programming), [Programming: Organizing Data](https://github.com/MathWorks-Teaching-Resources/Programming-Organizing-Data), [Programming: Structuring Code](https://github.com/MathWorks-Teaching-Resources/Programming-Structuring-Code).
37 |
38 |
39 | ## Getting Started
40 | ### Accessing the Module
41 | ### **On MATLAB Online:**
42 |
43 | Use the [
](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python&project=MATLABwithPython.prj) link to download the module. You will be prompted to log in or create a MathWorks account. The project will be loaded, and you will see an app with several navigation options to get you started.
44 |
45 | ### **On Desktop:**
46 |
47 | Download or clone this repository. Open MATLAB, navigate to the folder containing these scripts and double\-click on [MATLABwithPython.prj](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python&project=MATLABwithPython.prj&file=README.mlx). It will add the appropriate files to your MATLAB path and open an app that asks you where you would like to start.
48 |
49 |
50 | Ensure you have all the required products (listed below) installed. If you need to include a product, add it using the Add\-On Explorer. To install an add\-on, go to the **Home** tab and select
**Add-Ons** > **Get Add-Ons**.
51 |
52 |
53 | ## Products
54 |
55 | MATLAB® is used throughout. Tools from the Symbolic Math Toolbox™ are used to convert between different unit systems in the weather applications.
56 |
57 | # Scripts
58 | ## [**UsingMATLABwithPython.mlx**](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python&project=MATLABwithPython.prj&file=Scripts/UsingMATLABwithPython.mlx)
59 | | | |
60 | | :-- | :-- |
61 | | **Introductory script**
| **In this script, students will...**
|
62 | |
| $\bullet$ check that an appropriate version of Python is installed and visible within MATLAB
$\bullet$ explore the Run Python Code Live Task
$\bullet$ try running Python commands and a Python script from MATLAB
|
63 | | | |
64 |
65 | ## [**CheckingTheWeather.mlx**](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python&project=MATLABwithPython.prj&file=Scripts/CheckingTheWeather.mlx)
66 | | | |
67 | | :-- | :-- |
68 | | **Investigatory script**
| **In this script, students will...**
|
69 | |
| $\bullet$ set up an account with OpenWeather to create your own API key
$\bullet$ use existing Python code to make an API call to OpenWeather
$\bullet$ use MATLAB to explore the data returned by the API call, including data type conversions and unit conversions
|
70 | | | |
71 |
72 | ## [**CreateCurrentWeatherApp.mlx**](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python&project=MATLABwithPython.prj&file=Scripts/CreateCurrentWeatherApp.mlx)
73 | | | |
74 | | :-- | :-- |
75 | | **Application script**
| **In this script, students will...**
|
76 | |
| $\bullet$ use App Designer to build a custom app using the code from CheckingTheWeather.mlx
$\bullet$ create callbacks, properties, and functions
$\bullet$ design and organize a UI with drag and drop elements
$\bullet$ reuse code from CheckingTheWeather in a new context
|
77 | | | |
78 |
79 | # Apps
80 |
81 | Both of these apps require running Python from MATLAB, as set up in UsingMATLABwithPython and an OpenWeather API key, as set up in CheckingTheWeather.
82 |
83 | - **CurrentWeatherAppDemo.mlapp** shows the results of working through CreateCurrentWeatherApp.
84 | - **WeatherDisplay.mlapp** shows one elaborated version of the basic current weather app.
85 |
86 | # License
87 |
88 | The license for this module is available in the [LICENSE.md](https://github.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/blob/release/LICENSE.md).
89 |
90 | # Related Courseware Modules
91 | | | | |
92 | | :-- | :-- | :-- |
93 | | **Courseware Module**
| **Sample Content**
| **Available on:**
|
94 | | [**Fundamentals of Programming**](https://www.mathworks.com/matlabcentral/fileexchange/103225-fundamentals-of-programming)
Learn the basics of how to make a computer
accept, store, and compute with information
|
| [
](https://www.mathworks.com/matlabcentral/fileexchange/103225-fundamentals-of-programming)
[
](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Fundamentals-of-Programming&project=FundamentalsofProgramming.prj)
[GitHub](https://github.com/MathWorks-Teaching-Resources/Fundamentals-of-Programming)
|
95 | | [**Programming: Structuring Code**](https://www.mathworks.com/matlabcentral/fileexchange/115905-programming-structuring-code)
Learn how to organize your code into functions,
debug, comment, and share
|
| [
](https://www.mathworks.com/matlabcentral/fileexchange/115905-programming-structuring-code)
[
](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-Structuring-Code&project=StructuringCode.prj)
[GitHub](https://github.com/MathWorks-Teaching-Resources/Programming-Structuring-Code)
|
96 | | [**Programming: Organizing Data**](https://www.mathworks.com/matlabcentral/fileexchange/115900-programming-organizing-data)
Learn more about strings, numeric data types,
memory, and ways of storing data
|
| [
](https://www.mathworks.com/matlabcentral/fileexchange/115900-programming-organizing-data)
[
](https://matlab.mathworks.com/open/github/v1?repo=MathWorks-Teaching-Resources/Programming-Organizing-Data&project=OrganizingData.prj)
[GitHub](https://github.com/MathWorks-Teaching-Resources/Programming-Organizing-Data)
|
97 | | | | |
98 |
99 |
100 | Or feel free to explore our other [modular courseware content](https://www.mathworks.com/matlabcentral/fileexchange/?q=tag%3A%22courseware+module%22&sort=downloads_desc_30d).
101 |
102 | # Educator Resources
103 | - [Educator Page](https://www.mathworks.com/academia/educators.html)
104 |
105 | # Contribute
106 |
107 | Looking for more? Find an issue? Have a suggestion? Please contact the [MathWorks teaching resources team](mailto:%20onlineteaching@mathworks.com). If you want to contribute directly to this project, you can find information about how to do so in the [CONTRIBUTING.md](https://github.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/blob/release/CONTRIBUTING.md) page on GitHub.
108 |
109 | # Acknowledgments
110 |
111 | Many thanks to Blake Naccarato on his suggestions for improvement.
112 |
113 |
114 | *©* Copyright 2024 The MathWorks™, Inc
115 |
116 |
117 |
--------------------------------------------------------------------------------
/README.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/README.mlx
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Reporting Security Vulnerabilities
2 |
3 | If you believe you have discovered a security vulnerability, please report it to
4 | [security@mathworks.com](mailto:security@mathworks.com). Please see
5 | [MathWorks Vulnerability Disclosure Policy for Security Researchers](https://www.mathworks.com/company/aboutus/policies_statements/vulnerability-disclosure-policy.html)
6 | for additional information.
--------------------------------------------------------------------------------
/Scripts/CheckingTheWeather.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Scripts/CheckingTheWeather.mlx
--------------------------------------------------------------------------------
/Scripts/CreateCurrentWeatherApp.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Scripts/CreateCurrentWeatherApp.mlx
--------------------------------------------------------------------------------
/Scripts/UsingMATLABwithPython.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Scripts/UsingMATLABwithPython.mlx
--------------------------------------------------------------------------------
/Scripts/checkcurrentweather.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | '''
3 | Python 3.8 code
4 | Created on Thu Jan 4 20:41:45 2018
5 | Modified May 2022
6 |
7 | @author: Heather Gorr
8 | Updated by: Emma Smith Zbarsky
9 | Copyright 2018-2022 The MathWorks, Inc.
10 |
11 | Create the Openweather API-structured URL using One Call
12 | as described in the documentation
13 | https://openweathermap.org/api/one-call-api
14 | This API is licensed under CC BY-SA 4.0, as documented here:
15 | https://creativecommons.org/licenses/by-sa/4.0/
16 | '''
17 |
18 | # checkcurrentweather.py
19 | import datetime
20 | import json
21 | import urllib.request
22 |
23 | BASE_URL = 'http://api.openweathermap.org/data/2.5/weather?lat={}&lon={}&units={}&appid={}'
24 |
25 | def get_weather(lat,lon,apikey,**kwargs):
26 | '''get current conditions in specified location, e.g.,
27 | lat = 42.2775 N, lon = 71.3468 W is Natick, MA, US
28 | get_current_weather('42.2775','-71.3468',key,units='metric')'''
29 |
30 | # Initialize json_data
31 | json_data = {'Feedback': 'nothing'}
32 |
33 | # Set a default of imperial units
34 | info = {'units':'imperial'}
35 | for key, value in kwargs.items():
36 | info[key] = value
37 |
38 | try:
39 | url = BASE_URL.format(lat,lon,info['units'],apikey)
40 | json_data = json.loads(urllib.request.urlopen(url).read())
41 | except urllib.error.URLError:
42 | # if the One Call weather API doesn't work, return an error
43 | print('We cannot access the weather service')
44 |
45 | return json_data
46 |
47 |
48 | def parse_current_json(json_data):
49 | '''parse and extract json data from the current weather data'''
50 |
51 | # Initialize weather_info
52 | weather_info = {'Feedback': 'nothing'}
53 |
54 | try:
55 | # select data of interest from dictionary
56 | weather_info = json_data['main']
57 | # add current date and time
58 | weather_info['local_time'] = str(datetime.datetime.now())
59 | weather_info['current_time'] = json_data['dt']
60 | # make sure values are returned as floats
61 | weather_info['temp'] = float(weather_info['temp'])
62 | weather_info['feels_like'] = float(weather_info['feels_like'])
63 | weather_info['pressure'] = float(weather_info['pressure'])
64 | weather_info['humidity'] = float(weather_info['humidity'])
65 | weather_info['wind_speed'] = float(json_data['wind']['speed'])
66 | weather_info['wind_deg'] = float(json_data['wind']['deg'])
67 | weather_info['clouds'] = float(json_data['clouds']['all'])
68 | # Seconds shifted from UTC for location
69 | weather_info['timezone'] = json_data['timezone']
70 | # UTC Unix time
71 | weather_info['sunrise'] = json_data['sys']['sunrise']
72 | weather_info['sunset'] = json_data['sys']['sunset']
73 | # String
74 | weather_info['city_name'] = json_data['name']
75 | # Weather description as list
76 | weather_info['weather'] = json_data['weather']
77 |
78 | except KeyError as e:
79 | print('Something went wrong while parsing current json')
80 | raise e
81 |
82 | return weather_info
--------------------------------------------------------------------------------
/SoftwareTests/CheckTestResults.m:
--------------------------------------------------------------------------------
1 | classdef CheckTestResults < matlab.unittest.TestCase
2 |
3 | properties (SetAccess = protected)
4 | end
5 |
6 | properties (ClassSetupParameter)
7 | Project = {currentProject()};
8 | end
9 |
10 | properties (TestParameter)
11 | Version
12 | end
13 |
14 |
15 | methods (TestParameterDefinition,Static)
16 |
17 | function Version = GetResults(Project)
18 | RootFolder = Project.RootFolder;
19 | Version = dir(fullfile(RootFolder,"public","TestResults*.txt"));
20 | Version = extractBetween([Version.name],"TestResults_",".txt");
21 | end
22 |
23 | end
24 |
25 | methods (TestClassSetup)
26 |
27 | function SetUpSmokeTest(testCase,Project)
28 | try
29 | currentProject;
30 | catch
31 | error("Project is not loaded.")
32 | end
33 | end
34 |
35 | end
36 |
37 | methods(Test)
38 |
39 | function CheckResults(testCase,Version)
40 | File = fullfile("public","TestResults_"+Version+".txt");
41 | Results = readtable(File,TextType="string");
42 | if ~all(Results.Passed)
43 | error("Some of the tests did not pass.")
44 | end
45 | end
46 |
47 | end
48 |
49 | end
--------------------------------------------------------------------------------
/SoftwareTests/CreateBadge.m:
--------------------------------------------------------------------------------
1 | % Create the test suite with SmokeTest and Function test if they exist
2 | Suite = testsuite("CheckTestResults");
3 |
4 | % Create a runner with no plugins
5 | Runner = matlab.unittest.TestRunner.withNoPlugins;
6 |
7 | % Run the test suite
8 | Results = Runner.run(Suite);
9 |
10 | % Format the results in a table and save them
11 | Results = table(Results');
12 | Results = Results(Results.Passed,:);
13 | Version = extractBetween(string(Results.Name),"Version=",")");
14 |
15 |
16 | % Format the JSON file
17 | Badge = struct;
18 | Badge.schemaVersion = 1;
19 | Badge.label = "Tested with";
20 | if size(Results,1) >= 1
21 | Badge.color = "success"
22 | Badge.message = join(Version," | ");
23 | else
24 | Badge.color = "failure";
25 | Badge.message = "Pipeline fails";
26 | end
27 | Badge = jsonencode(Badge);
28 | writelines(Badge,fullfile("Images","TestedWith.json"));
--------------------------------------------------------------------------------
/SoftwareTests/FunctionTests.m:
--------------------------------------------------------------------------------
1 | classdef FunctionTests < matlab.unittest.TestCase
2 |
3 | % https://www.mathworks.com/help/matlab/matlab_prog/use-parameters-in-class-based-tests.html
4 |
5 | methods(Test)
6 |
7 | end % methods
8 |
9 | end % classdef
--------------------------------------------------------------------------------
/SoftwareTests/OrigSmokeTests.m:
--------------------------------------------------------------------------------
1 | classdef SmokeTests < matlab.unittest.TestCase
2 |
3 | properties (ClassSetupParameter)
4 | Project = {''};
5 | end
6 |
7 | properties (TestParameter)
8 | Scripts;
9 | end
10 |
11 | methods (TestParameterDefinition,Static)
12 |
13 | function Scripts = GetScriptName(Project)
14 | RootFolder = currentProject().RootFolder;
15 | Scripts = dir(fullfile(RootFolder,"Scripts","*.mlx"));
16 | Scripts = {Scripts.name};
17 | end
18 |
19 | end
20 |
21 | methods (TestClassSetup)
22 |
23 | function SetUpSmokeTest(testCase,Project)
24 | try
25 | currentProject;
26 | catch ME
27 | warning("Project is not loaded.")
28 | end
29 | end
30 |
31 |
32 | end
33 |
34 |
35 |
36 | methods(Test)
37 |
38 | function SmokeRun(testCase,Scripts)
39 | Filename = string(Scripts);
40 | switch (Filename)
41 | case "CreateCurrentWeatherApp.mlx"
42 | disp("Skipping " + Filename)
43 | case "CheckingTheWeather.mlx"
44 | txt = readlines("Response.json");
45 | pycode = ["import checkcurrentweather"
46 | "import json"
47 | ""
48 | "json_data = json.loads(txt)"
49 | "currentWeather = checkcurrentweather.parse_current_json(json_data)"
50 | ];
51 | APISmokeTest(testCase,Filename,pycode,txt)
52 | case "WeatherForecast.mlx"
53 | % txt = readlines("ResponseOneCall.json");
54 | % pycode = ["import checkweather"
55 | % ""
56 | % "json_data = json.loads(txt)"
57 | % "currentWeather = checkweather.parse_current_json(json_data)"
58 | % "forecastWeather = checkweather.parse_forecast_json(json_data)"
59 | % ];
60 | % APISmokeTest(testCase,Filename,pycode,txt)
61 | case "SampleWeatherDashboard.mlx"
62 |
63 | otherwise
64 | SimpleSmokeTest(testCase,Filename)
65 | end
66 | end
67 |
68 | end
69 |
70 |
71 | methods (Access = private)
72 |
73 | function APISmokeTest(testCase,Filename,pycode,txt)
74 | RootFolder = currentProject().RootFolder;
75 | cd(RootFolder)
76 | cd Scripts
77 | if Filename == "CheckingTheWeather.mlx"
78 | [currentWeather] = pyrun(pycode, "currentWeather","txt",txt);
79 | elseif Filename == "WeatherForecast.mlx"
80 | [currentWeather,forecastWeather] = pyrun(pycode,["currentWeather","forecastWeather"],"txt",txt);
81 | end
82 |
83 | disp(">> Running " + Filename);
84 | try
85 | run(fullfile(Filename));
86 | catch ME
87 | testCase.verifyTrue(false,ME.message);
88 | end
89 |
90 | try
91 | % Log the opened figures to the test reports
92 | Figures = findall(groot,'Type','figure');
93 | Figures = flipud(Figures);
94 | if ~isempty(Figures)
95 | for f = 1:size(Figures,1)
96 | FigDiag = matlab.unittest.diagnostics.FigureDiagnostic(Figures(f));
97 | log(testCase,1,FigDiag);
98 | end
99 | end
100 | catch ME
101 | disp("Failed to capture images")
102 | end
103 | close all
104 | end
105 |
106 | function RunMyFile(~,Filename)
107 | run(Filename);
108 | end
109 |
110 | function SimpleSmokeTest(testCase,Filename)
111 |
112 | % Run the Smoke test
113 | RootFolder = currentProject().RootFolder;
114 | cd(RootFolder)
115 | disp(">> Running " + Filename);
116 | try
117 | RunMyFile(testCase,Filename)
118 | catch ME
119 | testCase.verifyTrue(false,ME.message);
120 | end
121 |
122 | % Log the opened figures to the test reports
123 | try
124 | Figures = findall(groot,'Type','figure');
125 | Figures = flipud(Figures);
126 | if ~isempty(Figures)
127 | for f = 1:size(Figures,1)
128 | FigDiag = matlab.unittest.diagnostics.FigureDiagnostic(Figures(f));
129 | log(testCase,1,FigDiag);
130 | end
131 | end
132 | catch ME
133 | disp("Failed to capture figures")
134 | end
135 | close all
136 |
137 | end
138 |
139 | end
140 |
141 | methods (TestClassTeardown)
142 |
143 | function closeAllFigure(testCase)
144 | close all force % Close figure windows
145 | end
146 |
147 | end % methods (TestClassTeardown)
148 |
149 | end
--------------------------------------------------------------------------------
/SoftwareTests/PostFiles/PostCheckingTheWeather.m:
--------------------------------------------------------------------------------
1 | % Post-run script for CheckingTheWeather.mlx
2 | % ---- Post-run commands -----
3 |
4 |
--------------------------------------------------------------------------------
/SoftwareTests/PostFiles/PostCheckingTheWeatherSoln.m:
--------------------------------------------------------------------------------
1 | % Post-run script for CheckingTheWeatherSoln.mlx
2 | % ---- Post-run commands -----
3 |
4 | writelines("",fullfile(currentProject().RootFolder,"Scripts","myAPIkey.txt"))
5 | if exist(fullfile(currentProject().RootFolder,"InstructorResources","Solutions","Response.json"),"file")
6 | delete(fullfile(currentProject().RootFolder,"InstructorResources","Solutions","Response.json"))
7 | end
--------------------------------------------------------------------------------
/SoftwareTests/PostFiles/PostCreateCurrentWeatherApp.m:
--------------------------------------------------------------------------------
1 | % Post-run script for CreateCurrentWeatherApp.mlx
2 | % ---- Post-run commands -----
3 |
4 |
--------------------------------------------------------------------------------
/SoftwareTests/PostFiles/PostCreateCurrentWeatherAppSoln.m:
--------------------------------------------------------------------------------
1 | % Post-run script for CreateCurrentWeatherAppSoln.mlx
2 | % ---- Post-run commands -----
3 |
4 | delete(findall(groot,'Name','MATLAB App'))
--------------------------------------------------------------------------------
/SoftwareTests/PostFiles/PostUsingMATLABwithPython.m:
--------------------------------------------------------------------------------
1 | % Post-run script for UsingMATLABwithPython.mlx
2 | % ---- Post-run commands -----
3 |
4 |
--------------------------------------------------------------------------------
/SoftwareTests/PostFiles/PostUsingMATLABwithPythonSoln.m:
--------------------------------------------------------------------------------
1 | % Post-run script for UsingMATLABwithPythonSoln.mlx
2 | % ---- Post-run commands -----
3 |
4 |
--------------------------------------------------------------------------------
/SoftwareTests/PostSmokeTest.m:
--------------------------------------------------------------------------------
1 | function PostSmokeTest(ShowReport)
2 | arguments
3 | ShowReport (1,1) logical = false;
4 | end
5 |
6 | import matlab.unittest.plugins.TestRunnerPlugin;
7 |
8 | % Create the runner:
9 | Runner = matlab.unittest.TestRunner.withTextOutput;
10 |
11 | % Create report folder:
12 | Folder = fullfile(currentProject().RootFolder,"public");
13 | if ~isfolder(Folder)
14 | mkdir(Folder)
15 | end
16 |
17 | % Add HTML plugin:
18 | Plugin = matlab.unittest.plugins.TestReportPlugin.producingHTML(Folder,...
19 | "IncludingPassingDiagnostics",true,...
20 | "IncludingCommandWindowText",false,...
21 | "LoggingLevel",matlab.automation.Verbosity(1));
22 | Runner.addPlugin(Plugin);
23 |
24 |
25 | % Create Test Suite
26 | Suite = testsuite("CheckTestResults");
27 |
28 | % Run the test suite
29 | Results = Runner.run(Suite);
30 |
31 |
32 | % Format the results in a table and save them
33 | Results = table(Results');
34 | Version = extractBetween(string(Results.Name),"Version=",")");
35 | Passed = Results.Passed;
36 |
37 | % Add link to other report
38 | File = fileread(fullfile("public","index.html"));
39 | for iVer = 1:length(Version)
40 | File = replace(File,"Version="+Version(iVer),...
41 | sprintf('%s',Version(iVer),"Version="+Version(iVer)));
42 | end
43 | writelines(File,fullfile("public","index.html"),"WriteMode","overwrite");
44 |
45 | % Format the JSON file
46 | Badge = struct;
47 | Badge.schemaVersion = 1;
48 | Badge.label = "Test Status";
49 | if all(Passed)
50 | Badge.color = "success";
51 | Badge.message = join("R"+Version," | ");
52 | elseif any(Passed)
53 | Badge.color = "yellowgreen";
54 | Badge.message = join("R")
55 | elseif all(~Passed)
56 | Badge.color = "critical";
57 | Badge.message = join("R"+Version," | ");
58 | end
59 | Badge = jsonencode(Badge);
60 | writelines(Badge,fullfile("Images","TestedWith.json"));
61 |
62 | if ShowReport
63 | web(fullfile(Folder,"index.html"))
64 | end
65 |
66 | end
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/PreCheckingTheWeather.m:
--------------------------------------------------------------------------------
1 | % Pre-run script for CheckingTheWeather.mlx
2 | % ---- Known Issues -----
3 | KnownIssuesID = "";
4 | % ---- Pre-run commands -----
5 |
6 | txt = readlines("Response.json");
7 | curpath = pwd;
8 | mypath = fullfile(currentProject().RootFolder,"Scripts");
9 | cd(mypath)
10 | pycode = ["import checkcurrentweather"
11 | "import json"
12 | ""
13 | "json_data = json.loads(txt)"
14 | "currentWeather = checkcurrentweather.parse_current_json(json_data)"
15 | ];
16 | [currentWeather] = pyrun(pycode, "currentWeather","txt",txt);
17 | cd(curpath)
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/PreCheckingTheWeatherSoln.m:
--------------------------------------------------------------------------------
1 | % Pre-run script for CheckingTheWeatherSoln.mlx
2 | % ---- Known Issues -----
3 | KnownIssuesID = "";
4 | % ---- Pre-run commands -----
5 |
6 | try
7 | copyfile(fullfile(currentProject().RootFolder,"InternalFiles","Solutions","myAPIkey.txt"),...
8 | fullfile(currentProject().RootFolder,"Scripts","myAPIkey.txt"))
9 | catch
10 | copyfile("Response.json",fullfile(currentProject().RootFolder,"InstructorResources","Solutions","Response.json"))
11 | pycode = ["import checkcurrentweather"
12 | "import json"
13 | ""
14 | "json_data = json.load(open(""Response.json""))"
15 | "currentWeather = checkcurrentweather.parse_current_json(json_data)"
16 | ];
17 | apikey = "TestString";
18 | pyrun = @(txt,out,varargin)TestPyRun(pycode,out,varargin);
19 | end
20 |
21 | function out = TestPyRun(txt,in,varargin)
22 | out = pyrun(txt,in);
23 | end
24 |
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/PreCreateCurrentWeatherApp.m:
--------------------------------------------------------------------------------
1 | % Pre-run script for CreateCurrentWeatherApp.mlx
2 | % ---- Known Issues -----
3 | KnownIssuesID = "";
4 | % ---- Pre-run commands -----
5 |
6 | appdesigner = @()disp("Open App Designer here.");
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/PreCreateCurrentWeatherAppSoln.m:
--------------------------------------------------------------------------------
1 | % Pre-run script for CreateCurrentWeatherAppSoln.mlx
2 | % ---- Known Issues -----
3 | KnownIssuesID = "";
4 | % ---- Pre-run commands -----
5 |
6 | open = @(x)run(x);
7 |
8 |
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/PreUsingMATLABwithPython.m:
--------------------------------------------------------------------------------
1 | % Pre-run script for UsingMATLABwithPython.mlx
2 | % ---- Known Issues -----
3 | KnownIssuesID = "";
4 | % ---- Pre-run commands -----
5 |
6 |
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/PreUsingMATLABwithPythonSoln.m:
--------------------------------------------------------------------------------
1 | % Pre-run script for UsingMATLABwithPythonSoln.mlx
2 | % ---- Known Issues -----
3 | KnownIssuesID = "";
4 | % ---- Pre-run commands -----
5 |
6 |
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/Response.json:
--------------------------------------------------------------------------------
1 | {"coord":{"lon":-71.3468,"lat":42.2775},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":274.86,"feels_like":270.03,"temp_min":273.44,"temp_max":276.25,"pressure":1003,"humidity":76},"visibility":10000,"wind":{"speed":5.66,"deg":280,"gust":10.8},"clouds":{"all":75},"dt":1710986897,"sys":{"type":2,"id":2005486,"country":"US","sunrise":1710931672,"sunset":1710975450},"timezone":-14400,"id":4944994,"name":"Natick","cod":200}
--------------------------------------------------------------------------------
/SoftwareTests/PreFiles/ResponseOneCall.json:
--------------------------------------------------------------------------------
1 | {
2 | "lat":33.44,
3 | "lon":-94.04,
4 | "timezone":"America/Chicago",
5 | "timezone_offset":-18000,
6 | "current":{
7 | "dt":1684929490,
8 | "sunrise":1684926645,
9 | "sunset":1684977332,
10 | "temp":292.55,
11 | "feels_like":292.87,
12 | "pressure":1014,
13 | "humidity":89,
14 | "dew_point":290.69,
15 | "uvi":0.16,
16 | "clouds":53,
17 | "visibility":10000,
18 | "wind_speed":3.13,
19 | "wind_deg":93,
20 | "wind_gust":6.71,
21 | "weather":[
22 | {
23 | "id":803,
24 | "main":"Clouds",
25 | "description":"broken clouds",
26 | "icon":"04d"
27 | }
28 | ]
29 | },
30 | "minutely":[
31 | {
32 | "dt":1684929540,
33 | "precipitation":0
34 | }
35 | ],
36 | "hourly":[
37 | {
38 | "dt":1684926000,
39 | "temp":292.01,
40 | "feels_like":292.33,
41 | "pressure":1014,
42 | "humidity":91,
43 | "dew_point":290.51,
44 | "uvi":0,
45 | "clouds":54,
46 | "visibility":10000,
47 | "wind_speed":2.58,
48 | "wind_deg":86,
49 | "wind_gust":5.88,
50 | "weather":[
51 | {
52 | "id":803,
53 | "main":"Clouds",
54 | "description":"broken clouds",
55 | "icon":"04n"
56 | }
57 | ],
58 | "pop":0.15
59 | }
60 | ],
61 | "daily":[
62 | {
63 | "dt":1684951200,
64 | "sunrise":1684926645,
65 | "sunset":1684977332,
66 | "moonrise":1684941060,
67 | "moonset":1684905480,
68 | "moon_phase":0.16,
69 | "summary":"Expect a day of partly cloudy with rain",
70 | "temp":{
71 | "day":299.03,
72 | "min":290.69,
73 | "max":300.35,
74 | "night":291.45,
75 | "eve":297.51,
76 | "morn":292.55
77 | },
78 | "feels_like":{
79 | "day":299.21,
80 | "night":291.37,
81 | "eve":297.86,
82 | "morn":292.87
83 | },
84 | "pressure":1016,
85 | "humidity":59,
86 | "dew_point":290.48,
87 | "wind_speed":3.98,
88 | "wind_deg":76,
89 | "wind_gust":8.92,
90 | "weather":[
91 | {
92 | "id":500,
93 | "main":"Rain",
94 | "description":"light rain",
95 | "icon":"10d"
96 | }
97 | ],
98 | "clouds":92,
99 | "pop":0.47,
100 | "rain":0.15,
101 | "uvi":9.23
102 | }
103 | ],
104 | "alerts": [
105 | {
106 | "sender_name": "NWS Philadelphia - Mount Holly (New Jersey, Delaware, Southeastern Pennsylvania)",
107 | "event": "Small Craft Advisory",
108 | "start": 1684952747,
109 | "end": 1684988747,
110 | "description": "...SMALL CRAFT ADVISORY REMAINS IN EFFECT FROM 5 PM THIS\nAFTERNOON TO 3 AM EST FRIDAY...\n* WHAT...North winds 15 to 20 kt with gusts up to 25 kt and seas\n3 to 5 ft expected.\n* WHERE...Coastal waters from Little Egg Inlet to Great Egg\nInlet NJ out 20 nm, Coastal waters from Great Egg Inlet to\nCape May NJ out 20 nm and Coastal waters from Manasquan Inlet\nto Little Egg Inlet NJ out 20 nm.\n* WHEN...From 5 PM this afternoon to 3 AM EST Friday.\n* IMPACTS...Conditions will be hazardous to small craft.",
111 | "tags": []
112 | }
113 | ]
114 | }
--------------------------------------------------------------------------------
/SoftwareTests/Response.json:
--------------------------------------------------------------------------------
1 | {"coord":{"lon":-71.3468,"lat":42.2775},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":274.86,"feels_like":270.03,"temp_min":273.44,"temp_max":276.25,"pressure":1003,"humidity":76},"visibility":10000,"wind":{"speed":5.66,"deg":280,"gust":10.8},"clouds":{"all":75},"dt":1710986897,"sys":{"type":2,"id":2005486,"country":"US","sunrise":1710931672,"sunset":1710975450},"timezone":-14400,"id":4944994,"name":"Natick","cod":200}
--------------------------------------------------------------------------------
/SoftwareTests/ResponseOneCall.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "lat":33.44,
4 | "lon":-94.04,
5 | "timezone":"America/Chicago",
6 | "timezone_offset":-18000,
7 | "current":{
8 | "dt":1684929490,
9 | "sunrise":1684926645,
10 | "sunset":1684977332,
11 | "temp":292.55,
12 | "feels_like":292.87,
13 | "pressure":1014,
14 | "humidity":89,
15 | "dew_point":290.69,
16 | "uvi":0.16,
17 | "clouds":53,
18 | "visibility":10000,
19 | "wind_speed":3.13,
20 | "wind_deg":93,
21 | "wind_gust":6.71,
22 | "weather":[
23 | {
24 | "id":803,
25 | "main":"Clouds",
26 | "description":"broken clouds",
27 | "icon":"04d"
28 | }
29 | ]
30 | },
31 | "minutely":[
32 | {
33 | "dt":1684929540,
34 | "precipitation":0
35 | }
36 | ],
37 | "hourly":[
38 | {
39 | "dt":1684926000,
40 | "temp":292.01,
41 | "feels_like":292.33,
42 | "pressure":1014,
43 | "humidity":91,
44 | "dew_point":290.51,
45 | "uvi":0,
46 | "clouds":54,
47 | "visibility":10000,
48 | "wind_speed":2.58,
49 | "wind_deg":86,
50 | "wind_gust":5.88,
51 | "weather":[
52 | {
53 | "id":803,
54 | "main":"Clouds",
55 | "description":"broken clouds",
56 | "icon":"04n"
57 | }
58 | ],
59 | "pop":0.15
60 | }
61 | ],
62 | "daily":[
63 | {
64 | "dt":1684951200,
65 | "sunrise":1684926645,
66 | "sunset":1684977332,
67 | "moonrise":1684941060,
68 | "moonset":1684905480,
69 | "moon_phase":0.16,
70 | "summary":"Expect a day of partly cloudy with rain",
71 | "temp":{
72 | "day":299.03,
73 | "min":290.69,
74 | "max":300.35,
75 | "night":291.45,
76 | "eve":297.51,
77 | "morn":292.55
78 | },
79 | "feels_like":{
80 | "day":299.21,
81 | "night":291.37,
82 | "eve":297.86,
83 | "morn":292.87
84 | },
85 | "pressure":1016,
86 | "humidity":59,
87 | "dew_point":290.48,
88 | "wind_speed":3.98,
89 | "wind_deg":76,
90 | "wind_gust":8.92,
91 | "weather":[
92 | {
93 | "id":500,
94 | "main":"Rain",
95 | "description":"light rain",
96 | "icon":"10d"
97 | }
98 | ],
99 | "clouds":92,
100 | "pop":0.47,
101 | "rain":0.15,
102 | "uvi":9.23
103 | }
104 | ],
105 | "alerts": [
106 | {
107 | "sender_name": "NWS Philadelphia - Mount Holly (New Jersey, Delaware, Southeastern Pennsylvania)",
108 | "event": "Small Craft Advisory",
109 | "start": 1684952747,
110 | "end": 1684988747,
111 | "description": "...SMALL CRAFT ADVISORY REMAINS IN EFFECT FROM 5 PM THIS\nAFTERNOON TO 3 AM EST FRIDAY...\n* WHAT...North winds 15 to 20 kt with gusts up to 25 kt and seas\n3 to 5 ft expected.\n* WHERE...Coastal waters from Little Egg Inlet to Great Egg\nInlet NJ out 20 nm, Coastal waters from Great Egg Inlet to\nCape May NJ out 20 nm and Coastal waters from Manasquan Inlet\nto Little Egg Inlet NJ out 20 nm.\n* WHEN...From 5 PM this afternoon to 3 AM EST Friday.\n* IMPACTS...Conditions will be hazardous to small craft.",
112 | "tags": [
113 |
114 | ]
115 | }
116 | ]
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/SoftwareTests/ResponseOneCallOneLine.json:
--------------------------------------------------------------------------------
1 | {"lat":33.44,"lon":-94.04,"timezone":"America/Chicago","timezone_offset":-18000,"current":{"dt":1684929490,"sunrise":1684926645,"sunset":1684977332,"temp":292.55,"feels_like":292.87,"pressure":1014,"humidity":89,"dew_point":290.69,"uvi":0.16,"clouds":53,"visibility":10000,"wind_speed":3.13,"wind_deg":93,"wind_gust":6.71,"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}]},"minutely":[{"dt":1684929540,"precipitation":0}],"hourly":[{"dt":1684926000,"temp":292.01,"feels_like":292.33,"pressure":1014,"humidity":91,"dew_point":290.51,"uvi":0,"clouds":54,"visibility":10000,"wind_speed":2.58,"wind_deg":86,"wind_gust":5.88,"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"pop":0.15}],"daily":[{"dt":1684951200,"sunrise":1684926645,"sunset":1684977332,"moonrise":1684941060,"moonset":1684905480,"moon_phase":0.16,"summary":"Expect a day of partly cloudy with rain","temp":{"day":299.03,"min":290.69,"max":300.35,"night":291.45,"eve":297.51,"morn":292.55},"feels_like":{"day":299.21,"night":291.37,"eve":297.86,"morn":292.87},"pressure":1016,"humidity":59,"dew_point":290.48,"wind_speed":3.98,"wind_deg":76,"wind_gust":8.92,"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":92,"pop":0.47,"rain":0.15,"uvi":9.23} ],"alerts": [{"sender_name": "NWS Philadelphia - Mount Holly (New Jersey, Delaware, Southeastern Pennsylvania)","event": "Small Craft Advisory","start": 1684952747,"end": 1684988747,"description": "...SMALL CRAFT ADVISORY REMAINS IN EFFECT FROM 5 PM THIS\nAFTERNOON TO 3 AM EST FRIDAY...\n* WHAT...North winds 15 to 20 kt with gusts up to 25 kt and seas\n3 to 5 ft expected.\n* WHERE...Coastal waters from Little Egg Inlet to Great Egg\nInlet NJ out 20 nm, Coastal waters from Great Egg Inlet to\nCape May NJ out 20 nm and Coastal waters from Manasquan Inlet\nto Little Egg Inlet NJ out 20 nm.\n* WHEN...From 5 PM this afternoon to 3 AM EST Friday.\n* IMPACTS...Conditions will be hazardous to small craft.","tags": [ ]}] }
--------------------------------------------------------------------------------
/SoftwareTests/RunAllTests.m:
--------------------------------------------------------------------------------
1 | function RunAllTests(ShowReport)
2 | arguments
3 | ShowReport (1,1) logical = false;
4 | end
5 |
6 | import matlab.unittest.plugins.TestReportPlugin;
7 |
8 | % Create a runner
9 | Runner = matlab.unittest.TestRunner.withTextOutput;
10 | Folder = fullfile(currentProject().RootFolder,"public",version("-release"));
11 | if ~isfolder(Folder)
12 | mkdir(Folder)
13 | else
14 | rmdir(Folder,'s')
15 | mkdir(Folder)
16 | end
17 | Plugin = TestReportPlugin.producingHTML(Folder,...
18 | "IncludingPassingDiagnostics",true,...
19 | "IncludingCommandWindowText",true,...
20 | "LoggingLevel",matlab.automation.Verbosity(1));
21 | Runner.addPlugin(Plugin);
22 |
23 |
24 | % Create the test suite with SmokeTest and Function test if they exist
25 | Suite = testsuite("SmokeTests");
26 | Suite = [Suite testsuite("FunctionTests")];
27 | Suite = [Suite testsuite("SolnSmokeTests")];
28 |
29 | % Run the test suite
30 | Results = Runner.run(Suite);
31 |
32 | if ShowReport
33 | web(fullfile(Folder,"index.html"))
34 | end
35 |
36 | % Format the results in a table and save them
37 | ResultsTable = table(Results')
38 | writetable(ResultsTable,fullfile(currentProject().RootFolder,...
39 | "public","TestResults_"+version("-release")+".txt"));
40 |
41 | % Assert success of test
42 | assertSuccess(Results);
43 |
44 | end
45 |
--------------------------------------------------------------------------------
/SoftwareTests/SmokeTests.m:
--------------------------------------------------------------------------------
1 | classdef SmokeTests < matlab.unittest.TestCase
2 |
3 | properties
4 | RootFolder
5 | sparedEditors % Files already open when the test starts
6 | end % properties
7 |
8 | properties (ClassSetupParameter)
9 | Project = {currentProject()};
10 | end % ClassSetupParameter
11 |
12 | properties (TestParameter)
13 | File;
14 | end % TestParameter
15 |
16 | methods (TestParameterDefinition,Static)
17 |
18 | function File = RetrieveFile(Project) %#ok
19 | % Retrieve student template files:
20 | RootFolder = currentProject().RootFolder;
21 | File = dir(fullfile(RootFolder,"Scripts","*.mlx"));
22 | File = {File.name};
23 | end
24 |
25 | end % Static TestParameterDefinition
26 |
27 | methods (TestClassSetup)
28 |
29 | function SetUpSmokeTest(testCase,Project) %#ok
30 | % Navigate to project root folder:
31 | testCase.RootFolder = Project.RootFolder;
32 | cd(testCase.RootFolder)
33 |
34 | % Close the StartUp app if still open:
35 | delete(findall(groot,'Name','StartUp App'))
36 |
37 | % Log MATLAB version:
38 | testCase.log("Running in " + version)
39 | end
40 |
41 | end % TestClassSetup
42 |
43 | methods(TestMethodSetup)
44 | function recordEditorsToSpare(testCase)
45 | testCase.sparedEditors = matlab.desktop.editor.getAll;
46 | testCase.sparedEditors = {testCase.sparedEditors.Filename};
47 | end
48 | end % TestMethodSetup
49 |
50 | methods(TestMethodTeardown)
51 | function closeOpenedEditors_thenDeleteWorkingDir(testCase)
52 | openEditors = matlab.desktop.editor.getAll;
53 | for editor=openEditors(1:end)
54 | if any(strcmp(editor.Filename, testCase.sparedEditors))
55 | continue;
56 | end
57 | % if not on our list, close the file
58 | editor.close();
59 | end
60 | end
61 | end % TestMethodTeardown
62 |
63 | methods(Test)
64 |
65 | function SmokeRun(testCase,File)
66 |
67 | % Navigate to project root folder:
68 | cd(testCase.RootFolder)
69 | FileToRun = string(File);
70 |
71 | % Pre-test:
72 | PreFiles = CheckPreFile(testCase,FileToRun);
73 | run(PreFiles);
74 |
75 | % Run SmokeTest
76 | disp(">> Running " + FileToRun);
77 | try
78 | run(fullfile("Scripts",FileToRun));
79 | catch ME
80 |
81 | end
82 |
83 | % Post-test:
84 | PostFiles = CheckPostFile(testCase,FileToRun);
85 | run(PostFiles)
86 |
87 | % Log every figure created during run:
88 | Figures = findall(groot,'Type','figure');
89 | Figures = flipud(Figures);
90 | if ~isempty(Figures)
91 | for f = 1:size(Figures,1)
92 | if ~isempty(Figures(f).Number)
93 | FigDiag = matlab.unittest.diagnostics.FigureDiagnostic(Figures(f),'Formats','png');
94 | log(testCase,1,FigDiag);
95 | end
96 | end
97 | end
98 |
99 | % Close all figures and Simulink models
100 | close all force
101 | if any(matlab.addons.installedAddons().Name == "Simulink")
102 | bdclose all
103 | end
104 |
105 | % Rethrow error if any
106 | if exist("ME","var")
107 | if ~any(strcmp(ME.identifier,KnownIssuesID))
108 | rethrow(ME)
109 | end
110 | end
111 |
112 | end
113 |
114 | end % Test Methods
115 |
116 |
117 | methods (Access = private)
118 |
119 | function Path = CheckPreFile(testCase,Filename)
120 | PreFile = "Pre"+replace(Filename,".mlx",".m");
121 | PreFilePath = fullfile(testCase.RootFolder,"SoftwareTests","PreFiles",PreFile);
122 | if ~isfolder(fullfile(testCase.RootFolder,"SoftwareTests/PreFiles"))
123 | mkdir(fullfile(testCase.RootFolder,"SoftwareTests/PreFiles"))
124 | end
125 | if ~isfile(PreFilePath)
126 | writelines("% Pre-run script for "+Filename,PreFilePath)
127 | writelines("% ---- Known Issues -----",PreFilePath,'WriteMode','append');
128 | writelines("KnownIssuesID = "+char(34)+char(34)+";",PreFilePath,'WriteMode','append');
129 | writelines("% ---- Pre-run commands -----",PreFilePath,'WriteMode','append');
130 | writelines(" ",PreFilePath,'WriteMode','append');
131 | end
132 | Path = PreFilePath;
133 | end
134 |
135 | function Path = CheckPostFile(testCase,Filename)
136 | PostFile = "Post"+replace(Filename,".mlx",".m");
137 | PostFilePath = fullfile(testCase.RootFolder,"SoftwareTests","PostFiles",PostFile);
138 | if ~isfolder(fullfile(testCase.RootFolder,"SoftwareTests/PostFiles"))
139 | mkdir(fullfile(testCase.RootFolder,"SoftwareTests/PostFiles"))
140 | end
141 | if ~isfile(PostFilePath)
142 | writelines("% Post-run script for "+Filename,PostFilePath)
143 | writelines("% ---- Post-run commands -----",PostFilePath,'WriteMode','append');
144 | writelines(" ",PostFilePath,'WriteMode','append');
145 | end
146 | Path = PostFilePath;
147 | end
148 |
149 | end % Private Methods
150 |
151 | end % Smoketests
--------------------------------------------------------------------------------
/SoftwareTests/SolnSmokeTests.m:
--------------------------------------------------------------------------------
1 | classdef SolnSmokeTests < matlab.unittest.TestCase
2 |
3 | properties
4 | RootFolder
5 | isSolnOnPath
6 | sparedEditors % Track open files
7 | end % properties
8 |
9 | properties (ClassSetupParameter)
10 | Project = {currentProject()};
11 | end % ClassSetupParameter
12 |
13 | methods(TestMethodSetup)
14 | function recordEditorsToSpare(testCase)
15 | testCase.sparedEditors = matlab.desktop.editor.getAll;
16 | testCase.sparedEditors = {testCase.sparedEditors.Filename};
17 | end
18 | end % TestMethodSetup
19 |
20 | methods(TestMethodTeardown)
21 | function closeOpenedEditors_thenDeleteWorkingDir(testCase)
22 | openEditors = matlab.desktop.editor.getAll;
23 | for editor=openEditors(1:end)
24 | if any(strcmp(editor.Filename, testCase.sparedEditors))
25 | continue;
26 | end
27 | % if not on our list, close the file
28 | editor.close();
29 | end
30 | end
31 | end % TestMethodTeardown
32 |
33 | properties (TestParameter)
34 | File;
35 | end % TestParameter
36 |
37 | methods (TestParameterDefinition,Static)
38 |
39 | function File = GetScriptName(Project)
40 | % Retrieve student template files:
41 | RootFolder = Project.RootFolder;
42 | File = dir(fullfile(RootFolder,"Scripts","*.mlx"));
43 | File = {File.name};
44 | end
45 |
46 | end % Static TestParameterDefinition
47 |
48 | methods (TestClassSetup)
49 |
50 | function SetUpPath(testCase,Project)
51 | % Navigate to project root folder:
52 | testCase.RootFolder = Project.RootFolder;
53 | cd(testCase.RootFolder)
54 |
55 | % Check that solutions are on path:
56 | testCase.isSolnOnPath = isfolder("Solutions");
57 | if testCase.isSolnOnPath == 0
58 | addpath(genpath(fullfile(testCase.RootFolder,"InstructorResources","Solutions")))
59 | end
60 |
61 | % Close the StartUp app if still open:
62 | delete(findall(groot,'Name','StartUp App'))
63 |
64 | % Log MATLAB version:
65 | testCase.log("Running in " + version)
66 |
67 | end % function setUpPath
68 |
69 | end % methods (TestClassSetup)
70 |
71 | methods(Test)
72 |
73 | % Check that solutions files exist for each of the student
74 | % templates
75 | function ExistSolns(testCase,File)
76 | SolutionName = replace(string(File),".mlx","Soln.mlx");
77 | assert(exist(SolutionName,"file"),"Missing solutions for "+File);
78 | end
79 |
80 |
81 | function SmokeRun(testCase,File)
82 |
83 | % Navigate to project root folder:
84 | cd(testCase.RootFolder)
85 | FileToRun = replace(string(File),".mlx","Soln.mlx");
86 |
87 | % Pre-test:
88 | PreFiles = CheckPreFile(testCase,FileToRun);
89 | run(PreFiles);
90 |
91 | % Run SmokeTest
92 | disp(">> Running " + FileToRun);
93 | try
94 | run(fullfile("InstructorResources","Solutions",FileToRun));
95 | catch ME
96 |
97 | end
98 |
99 | % Post-test:
100 | PostFiles = CheckPostFile(testCase,FileToRun);
101 | run(PostFiles)
102 |
103 | % Log every figure created during run:
104 | Figures = findall(groot,'Type','figure');
105 | Figures = flipud(Figures);
106 | if ~isempty(Figures)
107 | for f = 1:size(Figures,1)
108 | if ~isempty(Figures(f).Number)
109 | FigDiag = matlab.unittest.diagnostics.FigureDiagnostic(Figures(f),'Formats','png');
110 | log(testCase,1,FigDiag);
111 | end
112 | end
113 | end
114 |
115 | % Close all figures and Simulink models
116 | close all force
117 | if any(matlab.addons.installedAddons().Name == "Simulink")
118 | bdclose all
119 | end
120 |
121 | % Rethrow error if any
122 | if exist("ME","var")
123 | if ~any(strcmp(ME.identifier,KnownIssuesID))
124 | rethrow(ME)
125 | end
126 | end
127 |
128 | end
129 |
130 | end % Test Methods
131 |
132 | methods (Access = private)
133 |
134 | function Path = CheckPreFile(testCase,Filename)
135 | PreFile = "Pre"+replace(Filename,".mlx",".m");
136 | PreFilePath = fullfile(testCase.RootFolder,"SoftwareTests","PreFiles",PreFile);
137 | if ~isfolder(fullfile(testCase.RootFolder,"SoftwareTests/PreFiles"))
138 | mkdir(fullfile(testCase.RootFolder,"SoftwareTests/PreFiles"))
139 | end
140 | if ~isfile(PreFilePath)
141 | writelines("% Pre-run script for "+Filename,PreFilePath)
142 | writelines("% ---- Known Issues -----",PreFilePath,'WriteMode','append');
143 | writelines("KnownIssuesID = "+char(34)+char(34)+";",PreFilePath,'WriteMode','append');
144 | writelines("% ---- Pre-run commands -----",PreFilePath,'WriteMode','append');
145 | writelines(" ",PreFilePath,'WriteMode','append');
146 | end
147 | Path = PreFilePath;
148 | end
149 |
150 | function Path = CheckPostFile(testCase,Filename)
151 | PostFile = "Post"+replace(Filename,".mlx",".m");
152 | PostFilePath = fullfile(testCase.RootFolder,"SoftwareTests","PostFiles",PostFile);
153 | if ~isfolder(fullfile(testCase.RootFolder,"SoftwareTests/PostFiles"))
154 | mkdir(fullfile(testCase.RootFolder,"SoftwareTests/PostFiles"))
155 | end
156 | if ~isfile(PostFilePath)
157 | writelines("% Post-run script for "+Filename,PostFilePath)
158 | writelines("% ---- Post-run commands -----",PostFilePath,'WriteMode','append');
159 | writelines(" ",PostFilePath,'WriteMode','append');
160 | end
161 | Path = PostFilePath;
162 | end
163 |
164 | end % Private Access Methods
165 |
166 | methods (TestClassTeardown)
167 |
168 | function ResetPath(testCase)
169 | if ~testCase.isSolnOnPath && exist("Solutions","dir")
170 | rmpath(genpath(fullfile(currentProject().RootFolder,"InstructorResources","Solutions")))
171 | end
172 | end
173 |
174 | end % TestClassTeardown
175 |
176 | end % SolnSmokeTests
177 |
--------------------------------------------------------------------------------
/SoftwareTests/TestResults_R2023a.txt:
--------------------------------------------------------------------------------
1 | Name,Passed,Failed,Incomplete,Duration,Details
2 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=CheckingTheWeather.mlx),1,0,0,8.2960691,
3 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=CreateCurrentWeatherApp.mlx),1,0,0,0.0004901,
4 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=SampleWeatherDashboard.mlx),1,0,0,0.0004588,
5 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=UsingMATLABwithPython.mlx),1,0,0,2.2924885,
6 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=WeatherForecast.mlx),1,0,0,0.3437829,
7 |
--------------------------------------------------------------------------------
/SoftwareTests/TestResults_R2024a.txt:
--------------------------------------------------------------------------------
1 | Name,Passed,Failed,Incomplete,Duration,Details
2 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=CheckingTheWeather.mlx),1,0,0,0.1316994,
3 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=CreateCurrentWeatherApp.mlx),1,0,0,0.0003877,
4 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=SampleWeatherDashboard.mlx),1,0,0,0.000197,
5 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=UsingMATLABwithPython.mlx),1,0,0,0.3888675,
6 | SmokeTests[Project=0x0_char]/SmokeRun(Scripts=WeatherForecast.mlx),1,0,0,0.0044386,
7 |
--------------------------------------------------------------------------------
/Utilities/OldVersions/CheckingTheWeatherOld.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Utilities/OldVersions/CheckingTheWeatherOld.mlx
--------------------------------------------------------------------------------
/Utilities/OldVersions/UsingMATLABwithPythonOld.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Utilities/OldVersions/UsingMATLABwithPythonOld.mlx
--------------------------------------------------------------------------------
/Utilities/ProjectShutdown.m:
--------------------------------------------------------------------------------
1 | % Close the StartUp app if still open:
2 | delete(findall(groot,'Name','StartUp App'))
--------------------------------------------------------------------------------
/Utilities/ProjectStartupApp.m:
--------------------------------------------------------------------------------
1 | classdef ProjectStartupApp < matlab.apps.AppBase
2 |
3 | % Properties that correspond to app components
4 | properties (Access = public)
5 | StartUpAppUIFigure matlab.ui.Figure
6 | TabGroup matlab.ui.container.TabGroup
7 | WelcomeTab matlab.ui.container.Tab
8 | Image matlab.ui.control.Image
9 | READMEButton matlab.ui.control.Button
10 | ReviewUsButton matlab.ui.control.Button
11 | MainMenuButton matlab.ui.control.Button
12 | WelcomeTitle matlab.ui.control.Label
13 | TabReview matlab.ui.container.Tab
14 | OtherButton matlab.ui.control.Button
15 | StudentButton matlab.ui.control.Button
16 | FacultyButton matlab.ui.control.Button
17 | Q1 matlab.ui.control.Label
18 | ReviewTitle matlab.ui.control.Label
19 | ReviewText matlab.ui.control.Label
20 | end
21 |
22 |
23 | properties (Access = private)
24 | GitHubOrganization = "MathWorks-Teaching-Resources"; % Description
25 | GitHubRepository = "Programming-A-Starter-Project-Using-MATLAB-and-Python";
26 | end
27 | %% How to customize the app?
28 | %{
29 |
30 | This StartUp app is designed to be customized to your module. It
31 | requires a minimum number of customization:
32 |
33 | 1. Change "Module Template" in app.WelcomeTitle by your module name
34 | 2. Change "Module Template" in app.ReviewTitle by your module name
35 | 3. Change the GitHubRepository (line 25) to the correct value
36 | 4. Change image in app.Image by the cover image you would like for your
37 | module. This image should be located in rootFolder/Images
38 | 5. Create your MS Form:
39 | a. Make a copy of the Faculty and the Student Template surveys
40 | b. Customize the name of the survey to match the name of your
41 | survey
42 | c. Click on "Collect responses", select "Anyone can respond" and
43 | copy the form link to SetupAppLinks (see step 6).
44 | 5. Create your MS Sway:
45 | a. Go to MS Sway
46 | b. Create a blank sway
47 | c. Add the name of your module to the title box
48 | d. Click "Share", Select "Anyone with a link", Select "View"
49 | e. Copy the sway link to SetupAppLinks (see step 6).
50 | 6. Add the Survey and Sway link to Utilities/SurveyLinks using
51 | SetupAppLinks.mlx in InternalFiles/RequiredFunctions/StartUpFcn
52 | 7. Save > Export to .m file and save the result as
53 | Utilities/ProjectStartupApp.m
54 |
55 | %}
56 |
57 | methods (Access = private, Static)
58 |
59 | function pingSway(app)
60 | try
61 | if ~ispref("MCCTEAM")
62 | load Utilities\SurveyLinks.mat SwayLink
63 | webread(SwayLink);
64 | end
65 | catch
66 | end
67 | end
68 |
69 | function openStudentForm(app)
70 | try
71 | load Utilities\SurveyLinks.mat StudentFormLink
72 | web(StudentFormLink);
73 | catch
74 | end
75 | end
76 |
77 | function openFacultyForm(app)
78 | try
79 | load Utilities\SurveyLinks.mat FacultyFormLink
80 | web(FacultyFormLink);
81 | catch
82 | end
83 | end
84 |
85 | function saveSettings(isReviewed,numLoad)
86 | try
87 | save(fullfile("Utilities","ProjectSettings.mat"),"isReviewed","numLoad");
88 | catch
89 | end
90 | end
91 |
92 | end
93 |
94 |
95 | % Callbacks that handle component events
96 | methods (Access = private)
97 |
98 | % Code that executes after component creation
99 | function startupFcn(app)
100 |
101 | % Switch tab to review if has not been reviewed yet
102 | if isfile(fullfile("Utilities","ProjectSettings.mat"))
103 | load(fullfile("Utilities","ProjectSettings.mat"),"isReviewed","numLoad");
104 | numLoad = numLoad + 1; % Increment counter
105 | else
106 | isReviewed = false;
107 | numLoad = 1; % Initialize counter
108 | end
109 |
110 | % Switch tab for review
111 | if ~isReviewed && numLoad > 2
112 | isReviewed = true;
113 | app.TabGroup.SelectedTab = app.TabReview;
114 | end
115 |
116 | % Save new settings
117 | app.saveSettings(isReviewed,numLoad)
118 |
119 | % Download links to survey (should only work when module goes
120 | % public on GitHub)
121 | try
122 | import matlab.net.*
123 | import matlab.net.http.*
124 |
125 | Request = RequestMessage;
126 | Request.Method = 'GET';
127 | Address = URI("http://api.github.com/repos/"+app.GitHubOrganization+...
128 | "/"+app.GitHubRepository+"/contents/Utilities/SurveyLinks.mat");
129 | Request.Header = HeaderField("X-GitHub-Api-Version","2022-11-28");
130 | Request.Header(2) = HeaderField("Accept","application/vnd.github+json");
131 | [Answer,~,~] = send(Request,Address);
132 | websave(fullfile("Utilities/SurveyLinks.mat"),Answer.Body.Data.download_url);
133 | catch
134 | end
135 |
136 | end
137 |
138 | % Close request function: StartUpAppUIFigure
139 | function StartUpAppUIFigureCloseRequest(app, event)
140 | if event.Source == app.READMEButton
141 | open README.mlx
142 | elseif event.Source == app.MainMenuButton
143 | open MainMenu.mlx
144 | elseif event.Source == app.FacultyButton
145 | open MainMenu.mlx
146 | elseif event.Source == app.StudentButton
147 | open MainMenu.mlx
148 | elseif event.Source == app.OtherButton
149 | open MainMenu.mlx
150 | else
151 | disp("Thank you for your time.")
152 | end
153 | delete(app)
154 | end
155 |
156 | % Button pushed function: MainMenuButton
157 | function MainMenuButtonPushed(app, event)
158 | StartUpAppUIFigureCloseRequest(app,event)
159 | end
160 |
161 | % Button pushed function: FacultyButton
162 | function FacultyButtonPushed(app, event)
163 | app.pingSway;
164 | app.openFacultyForm;
165 | StartUpAppUIFigureCloseRequest(app,event)
166 | end
167 |
168 | % Button pushed function: StudentButton
169 | function StudentButtonPushed(app, event)
170 | app.pingSway;
171 | app.openStudentForm;
172 | StartUpAppUIFigureCloseRequest(app,event)
173 | end
174 |
175 | % Button pushed function: OtherButton
176 | function OtherButtonPushed(app, event)
177 | app.pingSway;
178 | app.openStudentForm;
179 | StartUpAppUIFigureCloseRequest(app,event)
180 | end
181 |
182 | % Button pushed function: ReviewUsButton
183 | function ReviewUsButtonPushed(app, event)
184 | app.TabGroup.SelectedTab = app.TabReview;
185 | end
186 |
187 | % Button pushed function: READMEButton
188 | function READMEButtonPushed(app, event)
189 | StartUpAppUIFigureCloseRequest(app,event)
190 | end
191 | end
192 |
193 | % Component initialization
194 | methods (Access = private)
195 |
196 | % Create UIFigure and components
197 | function createComponents(app)
198 |
199 | % Create StartUpAppUIFigure and hide until all components are created
200 | app.StartUpAppUIFigure = uifigure('Visible', 'off');
201 | app.StartUpAppUIFigure.AutoResizeChildren = 'off';
202 | app.StartUpAppUIFigure.Position = [100 100 276 430];
203 | app.StartUpAppUIFigure.Name = 'StartUp App';
204 | app.StartUpAppUIFigure.Resize = 'off';
205 | app.StartUpAppUIFigure.CloseRequestFcn = createCallbackFcn(app, @StartUpAppUIFigureCloseRequest, true);
206 |
207 | % Create TabGroup
208 | app.TabGroup = uitabgroup(app.StartUpAppUIFigure);
209 | app.TabGroup.AutoResizeChildren = 'off';
210 | app.TabGroup.Position = [1 1 276 460];
211 |
212 | % Create WelcomeTab
213 | app.WelcomeTab = uitab(app.TabGroup);
214 | app.WelcomeTab.AutoResizeChildren = 'off';
215 | app.WelcomeTab.Title = 'Tab';
216 |
217 | % Create WelcomeTitle
218 | app.WelcomeTitle = uilabel(app.WelcomeTab);
219 | app.WelcomeTitle.HorizontalAlignment = 'center';
220 | app.WelcomeTitle.VerticalAlignment = 'top';
221 | app.WelcomeTitle.WordWrap = 'on';
222 | app.WelcomeTitle.FontSize = 24;
223 | app.WelcomeTitle.FontWeight = 'bold';
224 | app.WelcomeTitle.Position = [2 330 274 89];
225 | app.WelcomeTitle.Text = 'Programming: A Starter Project Using MATLAB with Python';
226 |
227 | % Create MainMenuButton
228 | app.MainMenuButton = uibutton(app.WelcomeTab, 'push');
229 | app.MainMenuButton.ButtonPushedFcn = createCallbackFcn(app, @MainMenuButtonPushed, true);
230 | app.MainMenuButton.FontSize = 18;
231 | app.MainMenuButton.Position = [59 96 161 35];
232 | app.MainMenuButton.Text = 'Main Menu';
233 |
234 | % Create ReviewUsButton
235 | app.ReviewUsButton = uibutton(app.WelcomeTab, 'push');
236 | app.ReviewUsButton.ButtonPushedFcn = createCallbackFcn(app, @ReviewUsButtonPushed, true);
237 | app.ReviewUsButton.FontSize = 18;
238 | app.ReviewUsButton.Position = [59 10 161 35];
239 | app.ReviewUsButton.Text = 'Review Us';
240 |
241 | % Create READMEButton
242 | app.READMEButton = uibutton(app.WelcomeTab, 'push');
243 | app.READMEButton.ButtonPushedFcn = createCallbackFcn(app, @READMEButtonPushed, true);
244 | app.READMEButton.FontSize = 18;
245 | app.READMEButton.Position = [59 53 161 35];
246 | app.READMEButton.Text = 'README';
247 |
248 | % Create Image
249 | app.Image = uiimage(app.WelcomeTab);
250 | app.Image.Position = [21 137 235 186];
251 | app.Image.ImageSource = 'windTokyo.gif';
252 |
253 | % Create TabReview
254 | app.TabReview = uitab(app.TabGroup);
255 | app.TabReview.AutoResizeChildren = 'off';
256 | app.TabReview.Title = 'Tab2';
257 | app.TabReview.HandleVisibility = 'off';
258 |
259 | % Create ReviewText
260 | app.ReviewText = uilabel(app.TabReview);
261 | app.ReviewText.HorizontalAlignment = 'center';
262 | app.ReviewText.VerticalAlignment = 'top';
263 | app.ReviewText.WordWrap = 'on';
264 | app.ReviewText.FontSize = 18;
265 | app.ReviewText.Position = [16 243 245 69];
266 | app.ReviewText.Text = 'Please help us improve your experience by answering a few questions.';
267 |
268 | % Create ReviewTitle
269 | app.ReviewTitle = uilabel(app.TabReview);
270 | app.ReviewTitle.HorizontalAlignment = 'center';
271 | app.ReviewTitle.VerticalAlignment = 'top';
272 | app.ReviewTitle.WordWrap = 'on';
273 | app.ReviewTitle.FontSize = 24;
274 | app.ReviewTitle.FontWeight = 'bold';
275 | app.ReviewTitle.Position = [2 326 274 93];
276 | app.ReviewTitle.Text = 'Programming: A Starter Project Using MATLAB with Python';
277 |
278 | % Create Q1
279 | app.Q1 = uilabel(app.TabReview);
280 | app.Q1.HorizontalAlignment = 'center';
281 | app.Q1.VerticalAlignment = 'top';
282 | app.Q1.WordWrap = 'on';
283 | app.Q1.FontSize = 18;
284 | app.Q1.FontWeight = 'bold';
285 | app.Q1.Position = [16 141 245 69];
286 | app.Q1.Text = 'What describes you best?';
287 |
288 | % Create FacultyButton
289 | app.FacultyButton = uibutton(app.TabReview, 'push');
290 | app.FacultyButton.ButtonPushedFcn = createCallbackFcn(app, @FacultyButtonPushed, true);
291 | app.FacultyButton.FontSize = 18;
292 | app.FacultyButton.Position = [64 127 150 40];
293 | app.FacultyButton.Text = 'Faculty';
294 |
295 | % Create StudentButton
296 | app.StudentButton = uibutton(app.TabReview, 'push');
297 | app.StudentButton.ButtonPushedFcn = createCallbackFcn(app, @StudentButtonPushed, true);
298 | app.StudentButton.FontSize = 18;
299 | app.StudentButton.Position = [64 80 150 40];
300 | app.StudentButton.Text = 'Student';
301 |
302 | % Create OtherButton
303 | app.OtherButton = uibutton(app.TabReview, 'push');
304 | app.OtherButton.ButtonPushedFcn = createCallbackFcn(app, @OtherButtonPushed, true);
305 | app.OtherButton.FontSize = 18;
306 | app.OtherButton.Position = [64 34 150 40];
307 | app.OtherButton.Text = 'Other';
308 |
309 | % Show the figure after all components are created
310 | app.StartUpAppUIFigure.Visible = 'on';
311 | end
312 | end
313 |
314 | % App creation and deletion
315 | methods (Access = public)
316 |
317 | % Construct app
318 | function app = ProjectStartupApp
319 |
320 | % Create UIFigure and components
321 | createComponents(app)
322 |
323 | % Register the app with App Designer
324 | registerApp(app, app.StartUpAppUIFigure)
325 |
326 | % Execute the startup function
327 | runStartupFcn(app, @startupFcn)
328 |
329 | if nargout == 0
330 | clear app
331 | end
332 | end
333 |
334 | % Code that executes before app deletion
335 | function delete(app)
336 |
337 | % Delete UIFigure when app is deleted
338 | delete(app.StartUpAppUIFigure)
339 | end
340 | end
341 | end
--------------------------------------------------------------------------------
/Utilities/SurveyLinks.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MathWorks-Teaching-Resources/Programming-A-Starter-Project-Using-MATLAB-and-Python/dc3d99fe7fb71628e1c30fdd08ac4320d3dc0f55/Utilities/SurveyLinks.mat
--------------------------------------------------------------------------------
/resources/project/2zjcQkVJSJ_AwC9M8R9BTSESRzc/QEd0x6jBcKf03RgXQ3y07QAWBCsd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/2zjcQkVJSJ_AwC9M8R9BTSESRzc/QEd0x6jBcKf03RgXQ3y07QAWBCsp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/2zjcQkVJSJ_AwC9M8R9BTSESRzc/_kanDHLwZvrSM1wrb2rL3R-TtpAd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/2zjcQkVJSJ_AwC9M8R9BTSESRzc/_kanDHLwZvrSM1wrb2rL3R-TtpAp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/2zjcQkVJSJ_AwC9M8R9BTSESRzc/b4fK1nwNVcMFfH2HWk_9bHC2cXcd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/2zjcQkVJSJ_AwC9M8R9BTSESRzc/b4fK1nwNVcMFfH2HWk_9bHC2cXcp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/6xhH2l9GP9loT6TdFn_Mo65sDHg/P8PSrqcBHMbGhqD2r1d9oc0h3TUd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/6xhH2l9GP9loT6TdFn_Mo65sDHg/P8PSrqcBHMbGhqD2r1d9oc0h3TUp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/-Yp4iI7AkN0RXWsqH_qBv8BSoUsd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/-Yp4iI7AkN0RXWsqH_qBv8BSoUsp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/5wkpcXVsAhrdVuZJuRCjlxSek_Yd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/5wkpcXVsAhrdVuZJuRCjlxSek_Yp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/897K1ZIAIxWZa69h7rzaFEkJJ1Yd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/897K1ZIAIxWZa69h7rzaFEkJJ1Yp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/LUM1KVG-kpiMYV7i1xDItZmUkVQd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/LUM1KVG-kpiMYV7i1xDItZmUkVQp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/SGHsdnqYqyGyYGQP-0wqh6AyERAd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/SGHsdnqYqyGyYGQP-0wqh6AyERAp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/TzEa1ML1Hz49sPNQX5JM6EE413Qd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/TzEa1ML1Hz49sPNQX5JM6EE413Qp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/Ur1esh7xN9L6aqDUKBE31DKE1Qod.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/Ur1esh7xN9L6aqDUKBE31DKE1Qop.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/VnvWkijFxdp8LV3ck_Qpq9eyOpMd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/VnvWkijFxdp8LV3ck_Qpq9eyOpMp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/WNBzWWmVwu8nwCU7p01ZJtQ5j-od.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/WNBzWWmVwu8nwCU7p01ZJtQ5j-op.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/gK0bzvM8fEYFwItc078tqn4EOmId.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/gK0bzvM8fEYFwItc078tqn4EOmIp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/h026LEbG6ImfsgAII1WcSM9Hnnod.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/h026LEbG6ImfsgAII1WcSM9Hnnop.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/nA_28eBnx5NCFw_vQVWFh5ohqUAd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/nA_28eBnx5NCFw_vQVWFh5ohqUAp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/w234j28OzyIgK86-1WWW6oJ1rp4d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/w234j28OzyIgK86-1WWW6oJ1rp4p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/xH29tmOwPG1ix8h2YNwMHPQ_-ukd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BT5hWoz-UTefONdqForZyI91O8Y/xH29tmOwPG1ix8h2YNwMHPQ_-ukp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BjxNC43HIPP8KZwg_cceb68ikkA/AHoLGOV6JxAa3mDfXPOye2W3psUd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BjxNC43HIPP8KZwg_cceb68ikkA/AHoLGOV6JxAa3mDfXPOye2W3psUp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BjxNC43HIPP8KZwg_cceb68ikkA/NvNsziUvXU2FO5oXU12jeMmASEwd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/BjxNC43HIPP8KZwg_cceb68ikkA/NvNsziUvXU2FO5oXU12jeMmASEwp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BjxNC43HIPP8KZwg_cceb68ikkA/dxW0rLxFMXm0cpQGCSkWQRi2YRsd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/BjxNC43HIPP8KZwg_cceb68ikkA/dxW0rLxFMXm0cpQGCSkWQRi2YRsp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/-upqjogKesBp3DwJRlG6KjrKvd4d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/-upqjogKesBp3DwJRlG6KjrKvd4p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/2vfmNT5dFMoKB5FDZBSr3ouDAL8d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/2vfmNT5dFMoKB5FDZBSr3ouDAL8p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/DxJWFQ6s-5tgLo-3uCpCdq16n-sd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/DxJWFQ6s-5tgLo-3uCpCdq16n-sp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/JzO7EW4RnUYzi9OV7qh3x-wX4z8d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/JzO7EW4RnUYzi9OV7qh3x-wX4z8p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Pq7gqYnkFyhKab7XB8O0iwQTIP0d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Pq7gqYnkFyhKab7XB8O0iwQTIP0p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_8KD0FwxV6biv7mEQTGecP1TTPgd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_8KD0FwxV6biv7mEQTGecP1TTPgp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/cn2Ee7NifKI7ffnw_Fjz5lrC1Qgd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/cn2Ee7NifKI7ffnw_Fjz5lrC1Qgp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/dzjyExK2OLpL1YhePZIjY4vjrpsd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/dzjyExK2OLpL1YhePZIjY4vjrpsp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/e7wCov_BYJUY6VsFZYx5ab3064gd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/e7wCov_BYJUY6VsFZYx5ab3064gp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikoU0GqEAVreEIpyvUR8mCIaiqUd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikoU0GqEAVreEIpyvUR8mCIaiqUp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/lMJoqU1GA86jWAvX6adHL2EbMzMd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/lMJoqU1GA86jWAvX6adHL2EbMzMp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/nBednXcpm1PUS8qxyRkFXdab-P4d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/nBednXcpm1PUS8qxyRkFXdab-P4p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/HoHDHQ_WvHAAKj5aJOrvrg_vpt8/xXlmKuOQ7YT_G1elNhbKQIUqSRMd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/HoHDHQ_WvHAAKj5aJOrvrg_vpt8/xXlmKuOQ7YT_G1elNhbKQIUqSRMp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/jYpi1Pu6k-AfWEJrahCTREe7wz0d.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/jYpi1Pu6k-AfWEJrahCTREe7wz0p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/xcK8fO1pjra5DR0jot5vrzlBV84d.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/xcK8fO1pjra5DR0jot5vrzlBV84p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/EyDhXb-HjEIhAYfuSMUxquCH4aYd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/EyDhXb-HjEIhAYfuSMUxquCH4aYp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/d1u4eIKNgMuS21WRxXrD0UScuR8d.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/d1u4eIKNgMuS21WRxXrD0UScuR8p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/gjXMbSOzqQJbg7H7bMF0OVGji80d.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/gjXMbSOzqQJbg7H7bMF0OVGji80p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/p5HYYVUpTuYgZwnT8QkkzaoJraUd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/p5HYYVUpTuYgZwnT8QkkzaoJraUp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/q4FWbcu8zEbneDjWzNwfvfvjQNAd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/q4FWbcu8zEbneDjWzNwfvfvjQNAp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/s-04wUzHjOhlMa1CW_zpJwm8iDMd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZN2RlSIbyWXhOxbxxI4hOawbMD4/s-04wUzHjOhlMa1CW_zpJwm8iDMp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/IeTljmmsHd59nip38CQ5y5dOQnQd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/IeTljmmsHd59nip38CQ5y5dOQnQp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/QOpe-1pctdftDIjwQLRdjOUZW44d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/QOpe-1pctdftDIjwQLRdjOUZW44p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/bzMXcEpQelehv3qzHYr9ceCGgIod.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/bzMXcEpQelehv3qzHYr9ceCGgIop.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/hy3T897OVbl4TCaWFBnKRKDU0M8d.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/ZdVxxv9BsNz7MGUxtEc6Pq3qh1M/hy3T897OVbl4TCaWFBnKRKDU0M8p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/iMwdHOXOBiBXhnA_li8gtEJVTjc/RMvf4mEDuznAOqU6SKNmIWErfxgd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/iMwdHOXOBiBXhnA_li8gtEJVTjc/RMvf4mEDuznAOqU6SKNmIWErfxgp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/iMwdHOXOBiBXhnA_li8gtEJVTjc/ZTr3GAe6p03ZVs2FdKKE0JsiFMQd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/iMwdHOXOBiBXhnA_li8gtEJVTjc/ZTr3GAe6p03ZVs2FdKKE0JsiFMQp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/iMwdHOXOBiBXhnA_li8gtEJVTjc/uIbyU9dPEHKvxjdwx5pD9PDDCZYd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/iMwdHOXOBiBXhnA_li8gtEJVTjc/uIbyU9dPEHKvxjdwx5pD9PDDCZYp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/2zjcQkVJSJ_AwC9M8R9BTSESRzcd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/2zjcQkVJSJ_AwC9M8R9BTSESRzcp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/BT5hWoz-UTefONdqForZyI91O8Yd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/BT5hWoz-UTefONdqForZyI91O8Yp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/BjxNC43HIPP8KZwg_cceb68ikkAd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/BjxNC43HIPP8KZwg_cceb68ikkAp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/KocSmEw1PpelhlG7ZNeMUdHVtywd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/KocSmEw1PpelhlG7ZNeMUdHVtywp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QMJD9OLFzxcTTbPOoh-ahQ4zTRUd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QMJD9OLFzxcTTbPOoh-ahQ4zTRUp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/R0IsxKENiOKovWZXASFjrmpbBCYd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/R0IsxKENiOKovWZXASFjrmpbBCYp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ZN2RlSIbyWXhOxbxxI4hOawbMD4d.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ZN2RlSIbyWXhOxbxxI4hOawbMD4p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ZdVxxv9BsNz7MGUxtEc6Pq3qh1Md.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ZdVxxv9BsNz7MGUxtEc6Pq3qh1Mp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/iMwdHOXOBiBXhnA_li8gtEJVTjcd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/iMwdHOXOBiBXhnA_li8gtEJVTjcp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/rh0jHbNfmojECiiHH7BQHmZTsWkd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/rh0jHbNfmojECiiHH7BQHmZTsWkp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/rnpMu7jn2QWt_rQcz8FJ-MxGzVId.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/rnpMu7jn2QWt_rQcz8FJ-MxGzVIp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/trBOSMFt-ZFz0tI8PrpBhVjGM5Md.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/trBOSMFt-ZFz0tI8PrpBhVjGM5Mp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/6x1BhZX_fLnKpcwqra0qFwv1jIgp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/6xhH2l9GP9loT6TdFn_Mo65sDHgp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/HoHDHQ_WvHAAKj5aJOrvrg_vpt8p.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/KAXfQgCar2Yb8zOxgvf9hdmLP1Ep.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/NmGqIpAwUJcXFyLjFAGnU9uyN5Yp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/WZRuNzqc-Db7NcQAZO8Y-R8U9ccp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/rootp.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/uuid-0192afd8-7310-46b8-ad07-aacb330fc399.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/project/uuid-366ca619-578a-4bc0-8012-bfa62d28c37f.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------