Commit 2f525670 authored by A.P.R.C. Abeyrathna's avatar A.P.R.C. Abeyrathna

Added V3

parent 8028c92f
...@@ -13,4 +13,3 @@ ...@@ -13,4 +13,3 @@
.externalNativeBuild .externalNativeBuild
.cxx .cxx
local.properties local.properties
.idea
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Android\.android\avd\Pixel_5_API_33.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2022-10-07T13:30:19.869460Z" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RenderSettings">
<option name="useLiveRendering" value="false" />
</component>
</project>
\ No newline at end of file
Date,Time,Day,Special,Congestion,Drving Speed,Stops,Weather,Distance,Travel Time
1/1/2019,6,Sunday,No,5,40,14,25,14.7,56
1/2/2019,7,Sunday,No,8,40,14,27,14.7,55
1/3/2019,8,Sunday,No,9,40,14,28,14.7,55
1/4/2019,9,Sunday,No,7,40,14,29,14.7,56
1/5/2019,10,Sunday,No,6,40,14,29,14.7,56
1/6/2019,11,Sunday,No,4,40,14,30,14.7,56
1/7/2019,12,Sunday,No,4,40,14,30,14.7,56
1/8/2019,13,Sunday,No,4,40,14,30,14.7,56
1/9/2019,14,Sunday,No,8,40,14,30,14.7,56
1/10/2019,15,Sunday,No,8,40,14,29,14.7,56
1/11/2019,16,Sunday,Yes,6,40,14,29,14.7,56
1/12/2019,17,Sunday,No,7,40,14,28,14.7,56
1/13/2019,18,Sunday,No,8,40,14,27,14.7,56
1/14/2019,19,Sunday,No,9,40,14,27,14.7,71
1/15/2019,20,Sunday,No,6,40,14,26,14.7,73
1/16/2019,21,Sunday,No,6,40,14,26,14.7,72
1/17/2019,22,Sunday,No,5,40,14,25,14.7,75
1/18/2019,6,Monday,No,5,40,14,25,14.7,56
1/19/2019,7,Monday,No,8,40,14,27,14.7,55
1/20/2019,8,Monday,No,9,40,14,28,14.7,55
1/21/2019,9,Monday,No,7,40,14,29,14.7,56
1/22/2019,10,Monday,No,6,40,14,29,14.7,56
1/23/2019,11,Monday,No,4,40,14,30,14.7,56
1/24/2019,12,Monday,No,4,40,14,30,14.7,56
1/25/2019,13,Monday,No,4,40,14,30,14.7,56
1/26/2019,14,Monday,No,8,40,14,30,14.7,56
1/27/2019,15,Monday,No,8,40,14,29,14.7,56
1/28/2019,16,Monday,Yes,6,40,14,29,14.7,56
1/29/2019,17,Monday,No,7,40,14,28,14.7,56
1/30/2019,18,Monday,No,8,40,14,27,14.7,56
1/31/2019,19,Monday,No,9,40,14,27,14.7,71
2/1/2019,20,Monday,No,6,40,14,26,14.7,73
2/2/2019,21,Monday,No,6,40,14,26,14.7,72
2/3/2019,22,Monday,No,5,40,14,25,14.7,75
2/4/2019,6,Tuesday,No,5,40,14,25,14.7,56
2/5/2019,7,Tuesday,No,8,40,14,27,14.7,55
2/6/2019,8,Tuesday,No,9,40,14,28,14.7,55
2/7/2019,9,Tuesday,No,7,40,14,29,14.7,56
2/8/2019,10,Tuesday,No,6,40,14,29,14.7,56
2/9/2019,11,Tuesday,No,4,40,14,30,14.7,56
2/10/2019,12,Tuesday,No,4,40,14,30,14.7,56
2/11/2019,13,Tuesday,No,4,40,14,30,14.7,56
2/12/2019,14,Tuesday,No,8,40,14,30,14.7,56
2/13/2019,15,Tuesday,No,8,40,14,29,14.7,56
2/14/2019,16,Tuesday,Yes,6,40,14,29,14.7,56
2/15/2019,17,Tuesday,No,7,40,14,28,14.7,56
2/16/2019,18,Tuesday,No,8,40,14,27,14.7,56
2/17/2019,19,Tuesday,No,9,40,14,27,14.7,71
2/18/2019,20,Tuesday,No,6,40,14,26,14.7,73
2/19/2019,21,Tuesday,No,6,40,14,26,14.7,72
2/20/2019,22,Tuesday,No,5,40,14,25,14.7,75
2/21/2019,6,Sunday,No,7,40,0,25,1.2,9
2/22/2019,6,Sunday,No,9,40,0,25,1.2,11
2/23/2019,6,Sunday,No,3,40,1,25,1.2,8
2/24/2019,6,Sunday,No,2,40,0,25,1.2,3
2/25/2019,6,Sunday,No,2,40,1,25,3,3
2/26/2019,17,Sunday,No,9,40,1,25,3,12
2/27/2019,17,Sunday,No,9,40,4,25,4.7,19
2/28/2019,17,Sunday,No,3,40,4,25,4.7,12
3/1/2019,17,Sunday,No,6,40,4,25,4.7,15
3/2/2019,6,Sunday,No,7,40,9,25,7.5,34
3/3/2019,6,Sunday,No,9,40,9,25,7.5,39
3/4/2019,6,Sunday,No,5,40,9,25,7.5,30
3/5/2019,6,Monday,No,5,40,12,25,10.1,36
3/6/2019,6,Monday,No,9,40,12,25,10.1,43
3/7/2019,6,Monday,No,3,40,12,25,10.1,33
3/8/2019,13,Monday,No,5,40,12,25,10.1,36
3/9/2019,13,Monday,No,9,40,12,25,10.1,43
3/10/2019,13,Monday,No,3,40,12,25,10.1,33
3/11/2019,6,Monday,No,5,40,12,25,12.1,43
3/12/2019,6,Monday,No,9,40,12,25,12.1,49
3/13/2019,6,Monday,No,3,40,12,25,12.1,40
3/14/2019,12,Monday,No,5,40,12,25,12.1,43
3/15/2019,12,Monday,No,9,40,12,25,12.1,49
3/16/2019,12,Monday,No,3,40,12,25,12.1,40
3/17/2019,6,Sunday,No,5,40,14,25,14.7,56
3/18/2019,7,Sunday,No,8,40,14,27,14.7,55
3/19/2019,8,Sunday,No,9,40,14,28,14.7,55
3/20/2019,9,Sunday,No,7,40,14,29,14.7,56
3/21/2019,10,Sunday,No,6,40,14,29,14.7,56
3/22/2019,11,Sunday,No,4,40,14,30,14.7,56
3/23/2019,12,Sunday,No,4,40,14,30,14.7,56
3/24/2019,13,Sunday,No,4,40,14,30,14.7,56
3/25/2019,14,Sunday,No,8,40,14,30,14.7,56
3/26/2019,15,Sunday,No,8,40,14,29,14.7,56
3/27/2019,16,Sunday,Yes,6,40,14,29,14.7,56
3/28/2019,17,Sunday,No,7,40,14,28,14.7,56
3/29/2019,18,Sunday,No,8,40,14,27,14.7,56
3/30/2019,19,Sunday,No,9,40,14,27,14.7,71
3/31/2019,20,Sunday,No,6,40,14,26,14.7,73
4/1/2019,21,Sunday,No,6,40,14,26,14.7,72
4/2/2019,22,Sunday,No,5,40,14,25,14.7,75
4/3/2019,6,Monday,No,5,40,14,25,14.7,56
4/4/2019,7,Monday,No,8,40,14,27,14.7,55
4/5/2019,8,Monday,No,9,40,14,28,14.7,55
4/6/2019,9,Monday,No,7,40,14,29,14.7,56
4/7/2019,10,Monday,No,6,40,14,29,14.7,56
4/8/2019,11,Monday,No,4,40,14,30,14.7,56
4/9/2019,12,Monday,No,4,40,14,30,14.7,56
4/10/2019,13,Monday,No,4,40,14,30,14.7,56
4/11/2019,14,Monday,No,8,40,14,30,14.7,56
4/12/2019,15,Monday,No,8,40,14,29,14.7,56
4/13/2019,16,Monday,Yes,6,40,14,29,14.7,56
4/14/2019,17,Monday,No,7,40,14,28,14.7,56
4/15/2019,18,Monday,No,8,40,14,27,14.7,56
4/16/2019,19,Monday,No,9,40,14,27,14.7,71
4/17/2019,20,Monday,No,6,40,14,26,14.7,73
4/18/2019,21,Monday,No,6,40,14,26,14.7,72
4/19/2019,22,Monday,No,5,40,14,25,14.7,75
4/20/2019,6,Tuesday,No,5,40,14,25,14.7,56
4/21/2019,7,Tuesday,No,8,40,14,27,14.7,55
4/22/2019,8,Tuesday,No,9,40,14,28,14.7,55
4/23/2019,9,Tuesday,No,7,40,14,29,14.7,56
4/24/2019,10,Tuesday,No,6,40,14,29,14.7,56
4/25/2019,11,Tuesday,No,4,40,14,30,14.7,56
4/26/2019,12,Tuesday,No,4,40,14,30,14.7,56
4/27/2019,13,Tuesday,No,4,40,14,30,14.7,56
4/28/2019,14,Tuesday,No,8,40,14,30,14.7,56
4/29/2019,15,Tuesday,No,8,40,14,29,14.7,56
4/30/2019,16,Tuesday,Yes,6,40,14,29,14.7,56
5/1/2019,17,Tuesday,No,7,40,14,28,14.7,56
5/2/2019,18,Tuesday,No,8,40,14,27,14.7,56
5/3/2019,19,Tuesday,No,9,40,14,27,14.7,71
5/4/2019,20,Tuesday,No,6,40,14,26,14.7,73
5/5/2019,21,Tuesday,No,6,40,14,26,14.7,72
5/6/2019,22,Tuesday,No,5,40,14,25,14.7,75
5/7/2019,6,Sunday,No,7,40,0,25,1.2,9
5/8/2019,6,Sunday,No,9,40,0,25,1.2,11
5/9/2019,6,Sunday,No,3,40,1,25,1.2,8
5/10/2019,6,Sunday,No,2,40,0,25,1.2,3
5/11/2019,6,Sunday,No,2,40,1,25,3,3
5/12/2019,17,Sunday,No,9,40,1,25,3,12
5/13/2019,17,Sunday,No,9,40,4,25,4.7,19
5/14/2019,17,Sunday,No,3,40,4,25,4.7,12
5/15/2019,17,Sunday,No,6,40,4,25,4.7,15
5/16/2019,6,Sunday,No,7,40,9,25,7.5,34
5/17/2019,6,Sunday,No,9,40,9,25,7.5,39
5/18/2019,6,Sunday,No,5,40,9,25,7.5,30
5/19/2019,6,Monday,No,5,40,12,25,10.1,36
5/20/2019,6,Monday,No,9,40,12,25,10.1,43
5/21/2019,6,Monday,No,3,40,12,25,10.1,33
5/22/2019,13,Monday,No,5,40,12,25,10.1,36
5/23/2019,13,Monday,No,9,40,12,25,10.1,43
5/24/2019,13,Monday,No,3,40,12,25,10.1,33
5/25/2019,6,Monday,No,5,40,12,25,12.1,43
5/26/2019,6,Monday,No,9,40,12,25,12.1,49
5/27/2019,6,Monday,No,3,40,12,25,12.1,40
5/28/2019,12,Monday,No,5,40,12,25,12.1,43
5/29/2019,12,Monday,No,9,40,12,25,12.1,49
5/30/2019,12,Monday,No,3,40,12,25,12.1,40
5/31/2019,6,Sunday,No,5,40,14,25,14.7,56
6/1/2019,7,Sunday,No,8,40,14,27,14.7,55
6/2/2019,8,Sunday,No,9,40,14,28,14.7,55
6/3/2019,9,Sunday,No,7,40,14,29,14.7,56
6/4/2019,10,Sunday,No,6,40,14,29,14.7,56
6/5/2019,11,Sunday,No,4,40,14,30,14.7,56
6/6/2019,12,Sunday,No,4,40,14,30,14.7,56
6/7/2019,13,Sunday,No,4,40,14,30,14.7,56
6/8/2019,14,Sunday,No,8,40,14,30,14.7,56
6/9/2019,15,Sunday,No,8,40,14,29,14.7,56
6/10/2019,16,Sunday,Yes,6,40,14,29,14.7,56
6/11/2019,17,Sunday,No,7,40,14,28,14.7,56
6/12/2019,18,Sunday,No,8,40,14,27,14.7,56
6/13/2019,19,Sunday,No,9,40,14,27,14.7,71
6/14/2019,20,Sunday,No,6,40,14,26,14.7,73
6/15/2019,21,Sunday,No,6,40,14,26,14.7,72
6/16/2019,22,Sunday,No,5,40,14,25,14.7,75
6/17/2019,6,Monday,No,5,40,14,25,14.7,56
6/18/2019,7,Monday,No,8,40,14,27,14.7,55
6/19/2019,8,Monday,No,9,40,14,28,14.7,55
6/20/2019,9,Monday,No,7,40,14,29,14.7,56
6/21/2019,10,Monday,No,6,40,14,29,14.7,56
6/22/2019,11,Monday,No,4,40,14,30,14.7,56
6/23/2019,12,Monday,No,4,40,14,30,14.7,56
6/24/2019,13,Monday,No,4,40,14,30,14.7,56
6/25/2019,14,Monday,No,8,40,14,30,14.7,56
6/26/2019,15,Monday,No,8,40,14,29,14.7,56
6/27/2019,16,Monday,Yes,6,40,14,29,14.7,56
6/28/2019,17,Monday,No,7,40,14,28,14.7,56
6/29/2019,18,Monday,No,8,40,14,27,14.7,56
6/30/2019,19,Monday,No,9,40,14,27,14.7,71
7/1/2019,20,Monday,No,6,40,14,26,14.7,73
7/2/2019,21,Monday,No,6,40,14,26,14.7,72
7/3/2019,22,Monday,No,5,40,14,25,14.7,75
7/4/2019,6,Tuesday,No,5,40,14,25,14.7,56
7/5/2019,7,Tuesday,No,8,40,14,27,14.7,55
7/6/2019,8,Tuesday,No,9,40,14,28,14.7,55
7/7/2019,9,Tuesday,No,7,40,14,29,14.7,56
7/8/2019,10,Tuesday,No,6,40,14,29,14.7,56
7/9/2019,11,Tuesday,No,4,40,14,30,14.7,56
7/10/2019,12,Tuesday,No,4,40,14,30,14.7,56
7/11/2019,13,Tuesday,No,4,40,14,30,14.7,56
7/12/2019,14,Tuesday,No,8,40,14,30,14.7,56
7/13/2019,15,Tuesday,No,8,40,14,29,14.7,56
7/14/2019,16,Tuesday,Yes,6,40,14,29,14.7,56
7/15/2019,17,Tuesday,No,7,40,14,28,14.7,56
7/16/2019,18,Tuesday,No,8,40,14,27,14.7,56
7/17/2019,19,Tuesday,No,9,40,14,27,14.7,71
7/18/2019,20,Tuesday,No,6,40,14,26,14.7,73
7/19/2019,21,Tuesday,No,6,40,14,26,14.7,72
7/20/2019,22,Tuesday,No,5,40,14,25,14.7,75
7/21/2019,6,Sunday,No,7,40,0,25,1.2,9
7/22/2019,6,Sunday,No,9,40,0,25,1.2,11
7/23/2019,6,Sunday,No,3,40,1,25,1.2,8
7/24/2019,6,Sunday,No,2,40,0,25,1.2,3
7/25/2019,6,Sunday,No,2,40,1,25,3,3
7/26/2019,17,Sunday,No,9,40,1,25,3,12
7/27/2019,17,Sunday,No,9,40,4,25,4.7,19
7/28/2019,17,Sunday,No,3,40,4,25,4.7,12
7/29/2019,17,Sunday,No,6,40,4,25,4.7,15
7/30/2019,6,Sunday,No,7,40,9,25,7.5,34
7/31/2019,6,Sunday,No,9,40,9,25,7.5,39
8/1/2019,6,Sunday,No,5,40,9,25,7.5,30
8/2/2019,6,Monday,No,5,40,12,25,10.1,36
8/3/2019,6,Monday,No,9,40,12,25,10.1,43
8/4/2019,6,Monday,No,3,40,12,25,10.1,33
8/5/2019,13,Monday,No,5,40,12,25,10.1,36
8/6/2019,13,Monday,No,9,40,12,25,10.1,43
8/7/2019,13,Monday,No,3,40,12,25,10.1,33
8/8/2019,6,Monday,No,5,40,12,25,12.1,43
8/9/2019,6,Monday,No,9,40,12,25,12.1,49
8/10/2019,6,Monday,No,3,40,12,25,12.1,40
8/11/2019,12,Monday,No,5,40,12,25,12.1,43
8/12/2019,12,Monday,No,9,40,12,25,12.1,49
8/13/2019,12,Monday,No,3,40,12,25,12.1,40
8/14/2019,6,Sunday,No,5,40,14,25,14.7,56
8/15/2019,7,Sunday,No,8,40,14,27,14.7,55
8/16/2019,8,Sunday,No,9,40,14,28,14.7,55
8/17/2019,9,Sunday,No,7,40,14,29,14.7,56
8/18/2019,10,Sunday,No,6,40,14,29,14.7,56
8/19/2019,11,Sunday,No,4,40,14,30,14.7,56
8/20/2019,12,Sunday,No,4,40,14,30,14.7,56
8/21/2019,13,Sunday,No,4,40,14,30,14.7,56
8/22/2019,14,Sunday,No,8,40,14,30,14.7,56
8/23/2019,15,Sunday,No,8,40,14,29,14.7,56
8/24/2019,16,Sunday,Yes,6,40,14,29,14.7,56
8/25/2019,17,Sunday,No,7,40,14,28,14.7,56
8/26/2019,18,Sunday,No,8,40,14,27,14.7,56
8/27/2019,19,Sunday,No,9,40,14,27,14.7,71
8/28/2019,20,Sunday,No,6,40,14,26,14.7,73
8/29/2019,21,Sunday,No,6,40,14,26,14.7,72
8/30/2019,22,Sunday,No,5,40,14,25,14.7,75
8/31/2019,6,Monday,No,5,40,14,25,14.7,56
9/1/2019,7,Monday,No,8,40,14,27,14.7,55
9/2/2019,8,Monday,No,9,40,14,28,14.7,55
9/3/2019,9,Monday,No,7,40,14,29,14.7,56
9/4/2019,10,Monday,No,6,40,14,29,14.7,56
9/5/2019,11,Monday,No,4,40,14,30,14.7,56
9/6/2019,12,Monday,No,4,40,14,30,14.7,56
9/7/2019,13,Monday,No,4,40,14,30,14.7,56
9/8/2019,14,Monday,No,8,40,14,30,14.7,56
9/9/2019,15,Monday,No,8,40,14,29,14.7,56
9/10/2019,16,Monday,Yes,6,40,14,29,14.7,56
9/11/2019,17,Monday,No,7,40,14,28,14.7,56
9/12/2019,18,Monday,No,8,40,14,27,14.7,56
9/13/2019,19,Monday,No,9,40,14,27,14.7,71
9/14/2019,20,Monday,No,6,40,14,26,14.7,73
9/15/2019,21,Monday,No,6,40,14,26,14.7,72
9/16/2019,22,Monday,No,5,40,14,25,14.7,75
9/17/2019,6,Tuesday,No,5,40,14,25,14.7,56
9/18/2019,7,Tuesday,No,8,40,14,27,14.7,55
9/19/2019,8,Tuesday,No,9,40,14,28,14.7,55
9/20/2019,9,Tuesday,No,7,40,14,29,14.7,56
9/21/2019,10,Tuesday,No,6,40,14,29,14.7,56
9/22/2019,11,Tuesday,No,4,40,14,30,14.7,56
9/23/2019,12,Tuesday,No,4,40,14,30,14.7,56
9/24/2019,13,Tuesday,No,4,40,14,30,14.7,56
9/25/2019,14,Tuesday,No,8,40,14,30,14.7,56
9/26/2019,15,Tuesday,No,8,40,14,29,14.7,56
9/27/2019,16,Tuesday,Yes,6,40,14,29,14.7,56
9/28/2019,17,Tuesday,No,7,40,14,28,14.7,56
9/29/2019,18,Tuesday,No,8,40,14,27,14.7,56
9/30/2019,19,Tuesday,No,9,40,14,27,14.7,71
10/1/2019,20,Tuesday,No,6,40,14,26,14.7,73
10/2/2019,21,Tuesday,No,6,40,14,26,14.7,72
10/3/2019,22,Tuesday,No,5,40,14,25,14.7,75
10/4/2019,6,Sunday,No,7,40,0,25,1.2,9
10/5/2019,6,Sunday,No,9,40,0,25,1.2,11
10/6/2019,6,Sunday,No,3,40,1,25,1.2,8
10/7/2019,6,Sunday,No,2,40,0,25,1.2,3
10/8/2019,6,Sunday,No,2,40,1,25,3,3
10/9/2019,17,Sunday,No,9,40,1,25,3,12
10/10/2019,17,Sunday,No,9,40,4,25,4.7,19
10/11/2019,17,Sunday,No,3,40,4,25,4.7,12
10/12/2019,17,Sunday,No,6,40,4,25,4.7,15
10/13/2019,6,Sunday,No,7,40,9,25,7.5,34
10/14/2019,6,Sunday,No,9,40,9,25,7.5,39
10/15/2019,6,Sunday,No,5,40,9,25,7.5,30
10/16/2019,6,Monday,No,5,40,12,25,10.1,36
10/17/2019,6,Monday,No,9,40,12,25,10.1,43
10/18/2019,6,Monday,No,3,40,12,25,10.1,33
10/19/2019,13,Monday,No,5,40,12,25,10.1,36
10/20/2019,13,Monday,No,9,40,12,25,10.1,43
10/21/2019,13,Monday,No,3,40,12,25,10.1,33
10/22/2019,6,Monday,No,5,40,12,25,12.1,43
10/23/2019,6,Monday,No,9,40,12,25,12.1,49
10/24/2019,6,Monday,No,3,40,12,25,12.1,40
10/25/2019,12,Monday,No,5,40,12,25,12.1,43
10/26/2019,12,Monday,No,9,40,12,25,12.1,49
10/27/2019,12,Monday,No,3,40,12,25,12.1,40
10/28/2019,6,Sunday,No,5,40,14,25,14.7,56
10/29/2019,7,Sunday,No,8,40,14,27,14.7,55
10/30/2019,8,Sunday,No,9,40,14,28,14.7,55
10/31/2019,9,Sunday,No,7,40,14,29,14.7,56
11/1/2019,10,Sunday,No,6,40,14,29,14.7,56
11/2/2019,11,Sunday,No,4,40,14,30,14.7,56
11/3/2019,12,Sunday,No,4,40,14,30,14.7,56
11/4/2019,13,Sunday,No,4,40,14,30,14.7,56
11/5/2019,14,Sunday,No,8,40,14,30,14.7,56
11/6/2019,15,Sunday,No,8,40,14,29,14.7,56
11/7/2019,16,Sunday,Yes,6,40,14,29,14.7,56
11/8/2019,17,Sunday,No,7,40,14,28,14.7,56
11/9/2019,18,Sunday,No,8,40,14,27,14.7,56
11/10/2019,19,Sunday,No,9,40,14,27,14.7,71
11/11/2019,20,Sunday,No,6,40,14,26,14.7,73
11/12/2019,21,Sunday,No,6,40,14,26,14.7,72
11/13/2019,22,Sunday,No,5,40,14,25,14.7,75
11/14/2019,6,Monday,No,5,40,14,25,14.7,56
11/15/2019,7,Monday,No,8,40,14,27,14.7,55
11/16/2019,8,Monday,No,9,40,14,28,14.7,55
11/17/2019,9,Monday,No,7,40,14,29,14.7,56
11/18/2019,10,Monday,No,6,40,14,29,14.7,56
11/19/2019,11,Monday,No,4,40,14,30,14.7,56
11/20/2019,12,Monday,No,4,40,14,30,14.7,56
11/21/2019,13,Monday,No,4,40,14,30,14.7,56
11/22/2019,14,Monday,No,8,40,14,30,14.7,56
11/23/2019,15,Monday,No,8,40,14,29,14.7,56
11/24/2019,16,Monday,Yes,6,40,14,29,14.7,56
11/25/2019,17,Monday,No,7,40,14,28,14.7,56
11/26/2019,18,Monday,No,8,40,14,27,14.7,56
11/27/2019,19,Monday,No,9,40,14,27,14.7,71
11/28/2019,20,Monday,No,6,40,14,26,14.7,73
11/29/2019,21,Monday,No,6,40,14,26,14.7,72
11/30/2019,22,Monday,No,5,40,14,25,14.7,75
12/1/2019,6,Tuesday,No,5,40,14,25,14.7,56
12/2/2019,7,Tuesday,No,8,40,14,27,14.7,55
12/3/2019,8,Tuesday,No,9,40,14,28,14.7,55
12/4/2019,9,Tuesday,No,7,40,14,29,14.7,56
12/5/2019,10,Tuesday,No,6,40,14,29,14.7,56
12/6/2019,11,Tuesday,No,4,40,14,30,14.7,56
12/7/2019,12,Tuesday,No,4,40,14,30,14.7,56
12/8/2019,13,Tuesday,No,4,40,14,30,14.7,56
12/9/2019,14,Tuesday,No,8,40,14,30,14.7,56
12/10/2019,15,Tuesday,No,8,40,14,29,14.7,56
12/11/2019,16,Tuesday,Yes,6,40,14,29,14.7,56
12/12/2019,17,Tuesday,No,7,40,14,28,14.7,56
12/13/2019,18,Tuesday,No,8,40,14,27,14.7,56
12/14/2019,19,Tuesday,No,9,40,14,27,14.7,71
12/15/2019,20,Tuesday,No,6,40,14,26,14.7,73
12/16/2019,21,Tuesday,No,6,40,14,26,14.7,72
12/17/2019,22,Tuesday,No,5,40,14,25,14.7,75
12/18/2019,6,Sunday,No,7,40,0,25,1.2,9
12/19/2019,6,Sunday,No,9,40,0,25,1.2,11
12/20/2019,6,Sunday,No,3,40,1,25,1.2,8
12/21/2019,6,Sunday,No,2,40,0,25,1.2,3
12/22/2019,6,Sunday,No,2,40,1,25,3,3
12/23/2019,17,Sunday,No,9,40,1,25,3,12
12/24/2019,17,Sunday,No,9,40,4,25,4.7,19
12/25/2019,17,Sunday,No,3,40,4,25,4.7,12
12/26/2019,17,Sunday,No,6,40,4,25,4.7,15
12/27/2019,6,Sunday,No,7,40,9,25,7.5,34
12/28/2019,6,Sunday,No,9,40,9,25,7.5,39
12/29/2019,6,Sunday,No,5,40,9,25,7.5,30
12/30/2019,6,Monday,No,5,40,12,25,10.1,36
12/31/2019,6,Monday,No,9,40,12,25,10.1,43
1/1/2020,6,Monday,No,3,40,12,25,10.1,33
1/2/2020,13,Monday,No,5,40,12,25,10.1,36
1/3/2020,13,Monday,No,9,40,12,25,10.1,43
1/4/2020,13,Monday,No,3,40,12,25,10.1,33
1/5/2020,6,Monday,No,5,40,12,25,12.1,43
1/6/2020,6,Monday,No,9,40,12,25,12.1,49
1/7/2020,6,Monday,No,3,40,12,25,12.1,40
1/8/2020,12,Monday,No,5,40,12,25,12.1,43
1/9/2020,12,Monday,No,9,40,12,25,12.1,49
1/10/2020,12,Monday,No,3,40,12,25,12.1,40
1/11/2020,6,Sunday,No,5,40,14,25,14.7,56
1/12/2020,7,Sunday,No,8,40,14,27,14.7,55
1/13/2020,8,Sunday,No,9,40,14,28,14.7,55
1/14/2020,9,Sunday,No,7,40,14,29,14.7,56
1/15/2020,10,Sunday,No,6,40,14,29,14.7,56
1/16/2020,11,Sunday,No,4,40,14,30,14.7,56
1/17/2020,12,Sunday,No,4,40,14,30,14.7,56
1/18/2020,13,Sunday,No,4,40,14,30,14.7,56
1/19/2020,14,Sunday,No,8,40,14,30,14.7,56
1/20/2020,15,Sunday,No,8,40,14,29,14.7,56
1/21/2020,16,Sunday,Yes,6,40,14,29,14.7,56
1/22/2020,17,Sunday,No,7,40,14,28,14.7,56
1/23/2020,18,Sunday,No,8,40,14,27,14.7,56
1/24/2020,19,Sunday,No,9,40,14,27,14.7,71
1/25/2020,20,Sunday,No,6,40,14,26,14.7,73
1/26/2020,21,Sunday,No,6,40,14,26,14.7,72
1/27/2020,22,Sunday,No,5,40,14,25,14.7,75
1/28/2020,6,Monday,No,5,40,14,25,14.7,56
1/29/2020,7,Monday,No,8,40,14,27,14.7,55
1/30/2020,8,Monday,No,9,40,14,28,14.7,55
1/31/2020,9,Monday,No,7,40,14,29,14.7,56
2/1/2020,10,Monday,No,6,40,14,29,14.7,56
2/2/2020,11,Monday,No,4,40,14,30,14.7,56
2/3/2020,12,Monday,No,4,40,14,30,14.7,56
2/4/2020,13,Monday,No,4,40,14,30,14.7,56
2/5/2020,14,Monday,No,8,40,14,30,14.7,56
2/6/2020,15,Monday,No,8,40,14,29,14.7,56
2/7/2020,16,Monday,Yes,6,40,14,29,14.7,56
2/8/2020,17,Monday,No,7,40,14,28,14.7,56
2/9/2020,18,Monday,No,8,40,14,27,14.7,56
2/10/2020,19,Monday,No,9,40,14,27,14.7,71
2/11/2020,20,Monday,No,6,40,14,26,14.7,73
2/12/2020,21,Monday,No,6,40,14,26,14.7,72
2/13/2020,22,Monday,No,5,40,14,25,14.7,75
2/14/2020,6,Tuesday,No,5,40,14,25,14.7,56
2/15/2020,7,Tuesday,No,8,40,14,27,14.7,55
2/16/2020,8,Tuesday,No,9,40,14,28,14.7,55
2/17/2020,9,Tuesday,No,7,40,14,29,14.7,56
2/18/2020,10,Tuesday,No,6,40,14,29,14.7,56
2/19/2020,11,Tuesday,No,4,40,14,30,14.7,56
2/20/2020,12,Tuesday,No,4,40,14,30,14.7,56
2/21/2020,13,Tuesday,No,4,40,14,30,14.7,56
2/22/2020,14,Tuesday,No,8,40,14,30,14.7,56
2/23/2020,15,Tuesday,No,8,40,14,29,14.7,56
2/24/2020,16,Tuesday,Yes,6,40,14,29,14.7,56
2/25/2020,17,Tuesday,No,7,40,14,28,14.7,56
2/26/2020,18,Tuesday,No,8,40,14,27,14.7,56
2/27/2020,19,Tuesday,No,9,40,14,27,14.7,71
2/28/2020,20,Tuesday,No,6,40,14,26,14.7,73
2/29/2020,21,Tuesday,No,6,40,14,26,14.7,72
3/1/2020,22,Tuesday,No,5,40,14,25,14.7,75
3/2/2020,6,Sunday,No,7,40,0,25,1.2,9
3/3/2020,6,Sunday,No,9,40,0,25,1.2,11
3/4/2020,6,Sunday,No,3,40,1,25,1.2,8
3/5/2020,6,Sunday,No,2,40,0,25,1.2,3
3/6/2020,6,Sunday,No,2,40,1,25,3,3
3/7/2020,17,Sunday,No,9,40,1,25,3,12
3/8/2020,17,Sunday,No,9,40,4,25,4.7,19
3/9/2020,17,Sunday,No,3,40,4,25,4.7,12
3/10/2020,17,Sunday,No,6,40,4,25,4.7,15
3/11/2020,6,Sunday,No,7,40,9,25,7.5,34
3/12/2020,6,Sunday,No,9,40,9,25,7.5,39
3/13/2020,6,Sunday,No,5,40,9,25,7.5,30
3/14/2020,6,Monday,No,5,40,12,25,10.1,36
3/15/2020,6,Monday,No,9,40,12,25,10.1,43
3/16/2020,6,Monday,No,3,40,12,25,10.1,33
3/17/2020,13,Monday,No,5,40,12,25,10.1,36
3/18/2020,13,Monday,No,9,40,12,25,10.1,43
3/19/2020,13,Monday,No,3,40,12,25,10.1,33
3/20/2020,6,Monday,No,5,40,12,25,12.1,43
3/21/2020,6,Monday,No,9,40,12,25,12.1,49
3/22/2020,6,Monday,No,3,40,12,25,12.1,40
3/23/2020,12,Monday,No,5,40,12,25,12.1,43
3/24/2020,12,Monday,No,9,40,12,25,12.1,49
3/25/2020,12,Monday,No,3,40,12,25,12.1,40
3/26/2020,6,Sunday,No,5,40,14,25,14.7,56
3/27/2020,7,Sunday,No,8,40,14,27,14.7,55
3/28/2020,8,Sunday,No,9,40,14,28,14.7,55
3/29/2020,9,Sunday,No,7,40,14,29,14.7,56
3/30/2020,10,Sunday,No,6,40,14,29,14.7,56
3/31/2020,11,Sunday,No,4,40,14,30,14.7,56
4/1/2020,12,Sunday,No,4,40,14,30,14.7,56
4/2/2020,13,Sunday,No,4,40,14,30,14.7,56
4/3/2020,14,Sunday,No,8,40,14,30,14.7,56
4/4/2020,15,Sunday,No,8,40,14,29,14.7,56
4/5/2020,16,Sunday,Yes,6,40,14,29,14.7,56
4/6/2020,17,Sunday,No,7,40,14,28,14.7,56
4/7/2020,18,Sunday,No,8,40,14,27,14.7,56
4/8/2020,19,Sunday,No,9,40,14,27,14.7,71
4/9/2020,20,Sunday,No,6,40,14,26,14.7,73
4/10/2020,21,Sunday,No,6,40,14,26,14.7,72
4/11/2020,22,Sunday,No,5,40,14,25,14.7,75
4/12/2020,6,Monday,No,5,40,14,25,14.7,56
4/13/2020,7,Monday,No,8,40,14,27,14.7,55
4/14/2020,8,Monday,No,9,40,14,28,14.7,55
4/15/2020,9,Monday,No,7,40,14,29,14.7,56
4/16/2020,10,Monday,No,6,40,14,29,14.7,56
4/17/2020,11,Monday,No,4,40,14,30,14.7,56
4/18/2020,12,Monday,No,4,40,14,30,14.7,56
4/19/2020,13,Monday,No,4,40,14,30,14.7,56
4/20/2020,14,Monday,No,8,40,14,30,14.7,56
4/21/2020,15,Monday,No,8,40,14,29,14.7,56
4/22/2020,16,Monday,Yes,6,40,14,29,14.7,56
4/23/2020,17,Monday,No,7,40,14,28,14.7,56
4/24/2020,18,Monday,No,8,40,14,27,14.7,56
4/25/2020,19,Monday,No,9,40,14,27,14.7,71
4/26/2020,20,Monday,No,6,40,14,26,14.7,73
4/27/2020,21,Monday,No,6,40,14,26,14.7,72
4/28/2020,22,Monday,No,5,40,14,25,14.7,75
4/29/2020,6,Tuesday,No,5,40,14,25,14.7,56
4/30/2020,7,Tuesday,No,8,40,14,27,14.7,55
5/1/2020,8,Tuesday,No,9,40,14,28,14.7,55
5/2/2020,9,Tuesday,No,7,40,14,29,14.7,56
5/3/2020,10,Tuesday,No,6,40,14,29,14.7,56
5/4/2020,11,Tuesday,No,4,40,14,30,14.7,56
5/5/2020,12,Tuesday,No,4,40,14,30,14.7,56
5/6/2020,13,Tuesday,No,4,40,14,30,14.7,56
5/7/2020,14,Tuesday,No,8,40,14,30,14.7,56
5/8/2020,15,Tuesday,No,8,40,14,29,14.7,56
5/9/2020,16,Tuesday,Yes,6,40,14,29,14.7,56
5/10/2020,17,Tuesday,No,7,40,14,28,14.7,56
5/11/2020,18,Tuesday,No,8,40,14,27,14.7,56
5/12/2020,19,Tuesday,No,9,40,14,27,14.7,71
5/13/2020,20,Tuesday,No,6,40,14,26,14.7,73
5/14/2020,21,Tuesday,No,6,40,14,26,14.7,72
5/15/2020,22,Tuesday,No,5,40,14,25,14.7,75
5/16/2020,6,Sunday,No,7,40,0,25,1.2,9
5/17/2020,6,Sunday,No,9,40,0,25,1.2,11
5/18/2020,6,Sunday,No,3,40,1,25,1.2,8
5/19/2020,6,Sunday,No,2,40,0,25,1.2,3
5/20/2020,6,Sunday,No,2,40,1,25,3,3
5/21/2020,17,Sunday,No,9,40,1,25,3,12
5/22/2020,17,Sunday,No,9,40,4,25,4.7,19
5/23/2020,17,Sunday,No,3,40,4,25,4.7,12
5/24/2020,17,Sunday,No,6,40,4,25,4.7,15
5/25/2020,6,Sunday,No,7,40,9,25,7.5,34
5/26/2020,6,Sunday,No,9,40,9,25,7.5,39
5/27/2020,6,Sunday,No,5,40,9,25,7.5,30
5/28/2020,6,Monday,No,5,40,12,25,10.1,36
5/29/2020,6,Monday,No,9,40,12,25,10.1,43
5/30/2020,6,Monday,No,3,40,12,25,10.1,33
5/31/2020,13,Monday,No,5,40,12,25,10.1,36
6/1/2020,13,Monday,No,9,40,12,25,10.1,43
6/2/2020,13,Monday,No,3,40,12,25,10.1,33
6/3/2020,6,Monday,No,5,40,12,25,12.1,43
6/4/2020,6,Monday,No,9,40,12,25,12.1,49
6/5/2020,6,Monday,No,3,40,12,25,12.1,40
6/6/2020,12,Monday,No,5,40,12,25,12.1,43
6/7/2020,12,Monday,No,9,40,12,25,12.1,49
6/8/2020,12,Monday,No,3,40,12,25,12.1,40
6/9/2020,6,Sunday,No,5,40,14,25,14.7,56
6/10/2020,7,Sunday,No,8,40,14,27,14.7,55
6/11/2020,8,Sunday,No,9,40,14,28,14.7,55
6/12/2020,9,Sunday,No,7,40,14,29,14.7,56
6/13/2020,10,Sunday,No,6,40,14,29,14.7,56
6/14/2020,11,Sunday,No,4,40,14,30,14.7,56
6/15/2020,12,Sunday,No,4,40,14,30,14.7,56
6/16/2020,13,Sunday,No,4,40,14,30,14.7,56
6/17/2020,14,Sunday,No,8,40,14,30,14.7,56
6/18/2020,15,Sunday,No,8,40,14,29,14.7,56
6/19/2020,16,Sunday,Yes,6,40,14,29,14.7,56
6/20/2020,17,Sunday,No,7,40,14,28,14.7,56
6/21/2020,18,Sunday,No,8,40,14,27,14.7,56
6/22/2020,19,Sunday,No,9,40,14,27,14.7,71
6/23/2020,20,Sunday,No,6,40,14,26,14.7,73
6/24/2020,21,Sunday,No,6,40,14,26,14.7,72
6/25/2020,22,Sunday,No,5,40,14,25,14.7,75
6/26/2020,6,Monday,No,5,40,14,25,14.7,56
6/27/2020,7,Monday,No,8,40,14,27,14.7,55
6/28/2020,8,Monday,No,9,40,14,28,14.7,55
6/29/2020,9,Monday,No,7,40,14,29,14.7,56
6/30/2020,10,Monday,No,6,40,14,29,14.7,56
7/1/2020,11,Monday,No,4,40,14,30,14.7,56
7/2/2020,12,Monday,No,4,40,14,30,14.7,56
7/3/2020,13,Monday,No,4,40,14,30,14.7,56
7/4/2020,14,Monday,No,8,40,14,30,14.7,56
7/5/2020,15,Monday,No,8,40,14,29,14.7,56
7/6/2020,16,Monday,Yes,6,40,14,29,14.7,56
7/7/2020,17,Monday,No,7,40,14,28,14.7,56
7/8/2020,18,Monday,No,8,40,14,27,14.7,56
7/9/2020,19,Monday,No,9,40,14,27,14.7,71
7/10/2020,20,Monday,No,6,40,14,26,14.7,73
7/11/2020,21,Monday,No,6,40,14,26,14.7,72
7/12/2020,22,Monday,No,5,40,14,25,14.7,75
7/13/2020,6,Tuesday,No,5,40,14,25,14.7,56
7/14/2020,7,Tuesday,No,8,40,14,27,14.7,55
7/15/2020,8,Tuesday,No,9,40,14,28,14.7,55
7/16/2020,9,Tuesday,No,7,40,14,29,14.7,56
7/17/2020,10,Tuesday,No,6,40,14,29,14.7,56
7/18/2020,11,Tuesday,No,4,40,14,30,14.7,56
7/19/2020,12,Tuesday,No,4,40,14,30,14.7,56
7/20/2020,13,Tuesday,No,4,40,14,30,14.7,56
7/21/2020,14,Tuesday,No,8,40,14,30,14.7,56
7/22/2020,15,Tuesday,No,8,40,14,29,14.7,56
7/23/2020,16,Tuesday,Yes,6,40,14,29,14.7,56
7/24/2020,17,Tuesday,No,7,40,14,28,14.7,56
7/25/2020,18,Tuesday,No,8,40,14,27,14.7,56
7/26/2020,19,Tuesday,No,9,40,14,27,14.7,71
7/27/2020,20,Tuesday,No,6,40,14,26,14.7,73
7/28/2020,21,Tuesday,No,6,40,14,26,14.7,72
7/29/2020,22,Tuesday,No,5,40,14,25,14.7,75
7/30/2020,6,Sunday,No,7,40,0,25,1.2,9
7/31/2020,6,Sunday,No,9,40,0,25,1.2,11
8/1/2020,6,Sunday,No,3,40,1,25,1.2,8
8/2/2020,6,Sunday,No,2,40,0,25,1.2,3
8/3/2020,6,Sunday,No,2,40,1,25,3,3
8/4/2020,17,Sunday,No,9,40,1,25,3,12
8/5/2020,17,Sunday,No,9,40,4,25,4.7,19
8/6/2020,17,Sunday,No,3,40,4,25,4.7,12
8/7/2020,17,Sunday,No,6,40,4,25,4.7,15
8/8/2020,6,Sunday,No,7,40,9,25,7.5,34
8/9/2020,6,Sunday,No,9,40,9,25,7.5,39
8/10/2020,6,Sunday,No,5,40,9,25,7.5,30
8/11/2020,6,Monday,No,5,40,12,25,10.1,36
8/12/2020,6,Monday,No,9,40,12,25,10.1,43
8/13/2020,6,Monday,No,3,40,12,25,10.1,33
8/14/2020,13,Monday,No,5,40,12,25,10.1,36
8/15/2020,13,Monday,No,9,40,12,25,10.1,43
8/16/2020,13,Monday,No,3,40,12,25,10.1,33
8/17/2020,6,Monday,No,5,40,12,25,12.1,43
8/18/2020,6,Monday,No,9,40,12,25,12.1,49
8/19/2020,6,Monday,No,3,40,12,25,12.1,40
8/20/2020,12,Monday,No,5,40,12,25,12.1,43
8/21/2020,12,Monday,No,9,40,12,25,12.1,49
8/22/2020,12,Monday,No,3,40,12,25,12.1,40
import time
import paho.mqtt.client as paho
from cryptography.fernet import Fernet
broker = "broker.hivemq.com"
# broker="192.168.1.206"
# define callback
def on_log(client, userdata, level, buf):
print("log: ", buf)
def on_message(client, userdata, message):
# time.sleep(1)
print("receive payload ", message.payload)
decrypted_message = cipher.decrypt(message.payload) # decrypted_message = cipher.decrypt(encrypted_message)
print("\nreceived message =", str(decrypted_message.decode("utf-8")))
client = paho.Client(
"client-pub") # create client object client1.on_publish = on_publish #assign function to callback client1.connect(broker,port) #establish connection client1.publish("house/bulb1","on")
client.on_log = on_log
######
client.on_message = on_message
#####encryption
# cipher_key = Fernet.generate_key()
cipher_key = b'WDrevvK8ZrPn8gmiNFjcOp2xovBr40TCwJlZOyI94IY='
cipher = Fernet(cipher_key)
message = b'on33'
# message = b'the quick brown fox jumps over the lazy dog'
encrypted_message = cipher.encrypt(message)
out_message = encrypted_message.decode() # turn it into a string to send
##
print("connecting to broker ", broker)
client.connect(broker) # connect
print("publishing encrypted message ", encrypted_message)
# out_message="on"
client.publish("house/bulb1", out_message) # publish
time.sleep(4)
client.disconnect() # disconnect
client.loop_stop() # stop loop
import time
import paho.mqtt.client as paho
from cryptography.fernet import Fernet
broker = "broker.hivemq.com"
# define callback
def on_log(client, userdata, level, buf):
print("log: ", buf)
def on_message(client, userdata, message):
# time.sleep(1)
print("receive payload ", message.payload)
if message.payload == encrypted_message:
print("\npublished and received messages are the same")
decrypted_message = cipher.decrypt(message.payload) # decrypted_message = cipher.decrypt(encrypted_message)
print("\nreceived message =", str(decrypted_message.decode("utf-8")))
client = paho.Client("client-001") # create client object client1.on_publish = on_publish
client.on_log = on_log
client.on_message = on_message
# encryption
cipher_key = Fernet.generate_key()
cipher = Fernet(cipher_key)
message = b'on'
# message = b'the quick brown fox jumps over the lazy dog'
encrypted_message = cipher.encrypt(message)
out_message = encrypted_message.decode() # turn it into a string to send
##
print("connecting to broker ", broker)
client.connect(broker) # connect
client.loop_start() # start loop to process received messages
print("subscribing ")
client.subscribe("house/bulb1") # subscribe
time.sleep(2)
print("publishing encrypted message ", encrypted_message)
# message="on"
client.publish("house/bulb1", out_message) # publish
time.sleep(4)
client.disconnect() # disconnect
client.loop_stop() # stop loop
import time
import paho.mqtt.client as paho
from cryptography.fernet import Fernet
broker = "broker.hivemq.com"
# broker="192.168.1.206"
# define callback
def on_log(client, userdata, level, buf):
print("log: ", buf)
def on_message(client, userdata, message):
# time.sleep(1)
print("receive payload ", message.payload)
decrypted_message = cipher.decrypt(message.payload) # decrypted_message = cipher.decrypt(encrypted_message)
print("\nreceived message =", str(decrypted_message.decode("utf-8")))
client = paho.Client(
"client-001") # create client object client1.on_publish = on_publish #assign function
# to callback client1.connect(broker,port) #establish connection client1.publish(
# "house/bulb1","on")
client.on_log = on_log
######
client.on_message = on_message
#####encryption
cipher_key = b'WDrevvK8ZrPn8gmiNFjcOp2xovBr40TCwJlZOyI94IY='
cipher = Fernet(cipher_key)
print("connecting to broker ", broker)
client.connect(broker) # connect
client.loop_start() # start loop to process received messages
print("subscribing ")
client.subscribe("house/bulb1") # subscribe
count = 0
while count < 60:
time.sleep(1)
count += 1
client.disconnect() # disconnect
client.loop_stop() # stop loop
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"data = pd.read_csv('BusTravelData.csv')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Time</th>\n",
" <th>Day</th>\n",
" <th>Special</th>\n",
" <th>Congestion</th>\n",
" <th>Drving Speed</th>\n",
" <th>Stops</th>\n",
" <th>Weather</th>\n",
" <th>Distance</th>\n",
" <th>Travel Time</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1/1/2019</td>\n",
" <td>6</td>\n",
" <td>Sunday</td>\n",
" <td>No</td>\n",
" <td>5</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>25</td>\n",
" <td>14.7</td>\n",
" <td>56</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1/2/2019</td>\n",
" <td>7</td>\n",
" <td>Sunday</td>\n",
" <td>No</td>\n",
" <td>8</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>27</td>\n",
" <td>14.7</td>\n",
" <td>55</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1/3/2019</td>\n",
" <td>8</td>\n",
" <td>Sunday</td>\n",
" <td>No</td>\n",
" <td>9</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>28</td>\n",
" <td>14.7</td>\n",
" <td>55</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1/4/2019</td>\n",
" <td>9</td>\n",
" <td>Sunday</td>\n",
" <td>No</td>\n",
" <td>7</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>29</td>\n",
" <td>14.7</td>\n",
" <td>56</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1/5/2019</td>\n",
" <td>10</td>\n",
" <td>Sunday</td>\n",
" <td>No</td>\n",
" <td>6</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>29</td>\n",
" <td>14.7</td>\n",
" <td>56</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Time Day Special Congestion Drving Speed Stops Weather \\\n",
"0 1/1/2019 6 Sunday No 5 40 14 25 \n",
"1 1/2/2019 7 Sunday No 8 40 14 27 \n",
"2 1/3/2019 8 Sunday No 9 40 14 28 \n",
"3 1/4/2019 9 Sunday No 7 40 14 29 \n",
"4 1/5/2019 10 Sunday No 6 40 14 29 \n",
"\n",
" Distance Travel Time \n",
"0 14.7 56 \n",
"1 14.7 55 \n",
"2 14.7 55 \n",
"3 14.7 56 \n",
"4 14.7 56 "
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Time</th>\n",
" <th>Day</th>\n",
" <th>Special</th>\n",
" <th>Congestion</th>\n",
" <th>Drving Speed</th>\n",
" <th>Stops</th>\n",
" <th>Weather</th>\n",
" <th>Distance</th>\n",
" <th>Travel Time</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>595</th>\n",
" <td>8/18/2020</td>\n",
" <td>6</td>\n",
" <td>Monday</td>\n",
" <td>No</td>\n",
" <td>9</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>49</td>\n",
" </tr>\n",
" <tr>\n",
" <th>596</th>\n",
" <td>8/19/2020</td>\n",
" <td>6</td>\n",
" <td>Monday</td>\n",
" <td>No</td>\n",
" <td>3</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>40</td>\n",
" </tr>\n",
" <tr>\n",
" <th>597</th>\n",
" <td>8/20/2020</td>\n",
" <td>12</td>\n",
" <td>Monday</td>\n",
" <td>No</td>\n",
" <td>5</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>43</td>\n",
" </tr>\n",
" <tr>\n",
" <th>598</th>\n",
" <td>8/21/2020</td>\n",
" <td>12</td>\n",
" <td>Monday</td>\n",
" <td>No</td>\n",
" <td>9</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>49</td>\n",
" </tr>\n",
" <tr>\n",
" <th>599</th>\n",
" <td>8/22/2020</td>\n",
" <td>12</td>\n",
" <td>Monday</td>\n",
" <td>No</td>\n",
" <td>3</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>40</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Time Day Special Congestion Drving Speed Stops \\\n",
"595 8/18/2020 6 Monday No 9 40 12 \n",
"596 8/19/2020 6 Monday No 3 40 12 \n",
"597 8/20/2020 12 Monday No 5 40 12 \n",
"598 8/21/2020 12 Monday No 9 40 12 \n",
"599 8/22/2020 12 Monday No 3 40 12 \n",
"\n",
" Weather Distance Travel Time \n",
"595 25 12.1 49 \n",
"596 25 12.1 40 \n",
"597 25 12.1 43 \n",
"598 25 12.1 49 \n",
"599 25 12.1 40 "
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.tail()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(600, 10)"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.shape"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Number of rows 600\n",
"Number of columns 10\n"
]
}
],
"source": [
"print(\"Number of rows\",data.shape[0])\n",
"print(\"Number of columns\",data.shape[1])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 600 entries, 0 to 599\n",
"Data columns (total 10 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 Date 600 non-null object \n",
" 1 Time 600 non-null int64 \n",
" 2 Day 600 non-null object \n",
" 3 Special 600 non-null object \n",
" 4 Congestion 600 non-null int64 \n",
" 5 Drving Speed 600 non-null int64 \n",
" 6 Stops 600 non-null int64 \n",
" 7 Weather 600 non-null int64 \n",
" 8 Distance 600 non-null float64\n",
" 9 Travel Time 600 non-null int64 \n",
"dtypes: float64(1), int64(6), object(3)\n",
"memory usage: 47.0+ KB\n"
]
}
],
"source": [
"data.info()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Time</th>\n",
" <th>Congestion</th>\n",
" <th>Drving Speed</th>\n",
" <th>Stops</th>\n",
" <th>Weather</th>\n",
" <th>Distance</th>\n",
" <th>Travel Time</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>600.000000</td>\n",
" <td>600.000000</td>\n",
" <td>600.0</td>\n",
" <td>600.000000</td>\n",
" <td>600.000000</td>\n",
" <td>600.00000</td>\n",
" <td>600.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>12.546667</td>\n",
" <td>6.253333</td>\n",
" <td>40.0</td>\n",
" <td>12.000000</td>\n",
" <td>27.000000</td>\n",
" <td>12.40400</td>\n",
" <td>49.786667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>5.184524</td>\n",
" <td>2.035369</td>\n",
" <td>0.0</td>\n",
" <td>4.033251</td>\n",
" <td>1.961227</td>\n",
" <td>4.05381</td>\n",
" <td>17.968470</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>6.000000</td>\n",
" <td>2.000000</td>\n",
" <td>40.0</td>\n",
" <td>0.000000</td>\n",
" <td>25.000000</td>\n",
" <td>1.20000</td>\n",
" <td>3.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>7.000000</td>\n",
" <td>5.000000</td>\n",
" <td>40.0</td>\n",
" <td>12.000000</td>\n",
" <td>25.000000</td>\n",
" <td>12.10000</td>\n",
" <td>43.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>12.000000</td>\n",
" <td>6.000000</td>\n",
" <td>40.0</td>\n",
" <td>14.000000</td>\n",
" <td>27.000000</td>\n",
" <td>14.70000</td>\n",
" <td>56.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>17.000000</td>\n",
" <td>8.000000</td>\n",
" <td>40.0</td>\n",
" <td>14.000000</td>\n",
" <td>29.000000</td>\n",
" <td>14.70000</td>\n",
" <td>56.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>22.000000</td>\n",
" <td>9.000000</td>\n",
" <td>40.0</td>\n",
" <td>14.000000</td>\n",
" <td>30.000000</td>\n",
" <td>14.70000</td>\n",
" <td>75.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Time Congestion Drving Speed Stops Weather \\\n",
"count 600.000000 600.000000 600.0 600.000000 600.000000 \n",
"mean 12.546667 6.253333 40.0 12.000000 27.000000 \n",
"std 5.184524 2.035369 0.0 4.033251 1.961227 \n",
"min 6.000000 2.000000 40.0 0.000000 25.000000 \n",
"25% 7.000000 5.000000 40.0 12.000000 25.000000 \n",
"50% 12.000000 6.000000 40.0 14.000000 27.000000 \n",
"75% 17.000000 8.000000 40.0 14.000000 29.000000 \n",
"max 22.000000 9.000000 40.0 14.000000 30.000000 \n",
"\n",
" Distance Travel Time \n",
"count 600.00000 600.000000 \n",
"mean 12.40400 49.786667 \n",
"std 4.05381 17.968470 \n",
"min 1.20000 3.000000 \n",
"25% 12.10000 43.000000 \n",
"50% 14.70000 56.000000 \n",
"75% 14.70000 56.000000 \n",
"max 14.70000 75.000000 "
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.describe()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(['Sunday', 'Monday', 'Tuesday'], dtype=object)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data['Day'].unique()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 0\n",
"1 0\n",
"2 0\n",
"3 0\n",
"4 0\n",
" ..\n",
"595 1\n",
"596 1\n",
"597 1\n",
"598 1\n",
"599 1\n",
"Name: Day, Length: 600, dtype: int64"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data['Day'].map({'Sunday':0,'Monday':1,'Tuesday':2})"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"data['Day'] = data['Day'].map({'Sunday':0,'Monday':1,'Tuesday':2})"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Time</th>\n",
" <th>Day</th>\n",
" <th>Special</th>\n",
" <th>Congestion</th>\n",
" <th>Drving Speed</th>\n",
" <th>Stops</th>\n",
" <th>Weather</th>\n",
" <th>Distance</th>\n",
" <th>Travel Time</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1/1/2019</td>\n",
" <td>6</td>\n",
" <td>0</td>\n",
" <td>No</td>\n",
" <td>5</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>25</td>\n",
" <td>14.7</td>\n",
" <td>56</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1/2/2019</td>\n",
" <td>7</td>\n",
" <td>0</td>\n",
" <td>No</td>\n",
" <td>8</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>27</td>\n",
" <td>14.7</td>\n",
" <td>55</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1/3/2019</td>\n",
" <td>8</td>\n",
" <td>0</td>\n",
" <td>No</td>\n",
" <td>9</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>28</td>\n",
" <td>14.7</td>\n",
" <td>55</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1/4/2019</td>\n",
" <td>9</td>\n",
" <td>0</td>\n",
" <td>No</td>\n",
" <td>7</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>29</td>\n",
" <td>14.7</td>\n",
" <td>56</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1/5/2019</td>\n",
" <td>10</td>\n",
" <td>0</td>\n",
" <td>No</td>\n",
" <td>6</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>29</td>\n",
" <td>14.7</td>\n",
" <td>56</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Time Day Special Congestion Drving Speed Stops Weather \\\n",
"0 1/1/2019 6 0 No 5 40 14 25 \n",
"1 1/2/2019 7 0 No 8 40 14 27 \n",
"2 1/3/2019 8 0 No 9 40 14 28 \n",
"3 1/4/2019 9 0 No 7 40 14 29 \n",
"4 1/5/2019 10 0 No 6 40 14 29 \n",
"\n",
" Distance Travel Time \n",
"0 14.7 56 \n",
"1 14.7 55 \n",
"2 14.7 55 \n",
"3 14.7 56 \n",
"4 14.7 56 "
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"data['Special'] = data['Special'].map({'No':0,'Yes':1})"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Time</th>\n",
" <th>Day</th>\n",
" <th>Special</th>\n",
" <th>Congestion</th>\n",
" <th>Drving Speed</th>\n",
" <th>Stops</th>\n",
" <th>Weather</th>\n",
" <th>Distance</th>\n",
" <th>Travel Time</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>595</th>\n",
" <td>8/18/2020</td>\n",
" <td>6</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>9</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>49</td>\n",
" </tr>\n",
" <tr>\n",
" <th>596</th>\n",
" <td>8/19/2020</td>\n",
" <td>6</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>3</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>40</td>\n",
" </tr>\n",
" <tr>\n",
" <th>597</th>\n",
" <td>8/20/2020</td>\n",
" <td>12</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>43</td>\n",
" </tr>\n",
" <tr>\n",
" <th>598</th>\n",
" <td>8/21/2020</td>\n",
" <td>12</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>9</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>49</td>\n",
" </tr>\n",
" <tr>\n",
" <th>599</th>\n",
" <td>8/22/2020</td>\n",
" <td>12</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>3</td>\n",
" <td>40</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>12.1</td>\n",
" <td>40</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Time Day Special Congestion Drving Speed Stops Weather \\\n",
"595 8/18/2020 6 1 0 9 40 12 25 \n",
"596 8/19/2020 6 1 0 3 40 12 25 \n",
"597 8/20/2020 12 1 0 5 40 12 25 \n",
"598 8/21/2020 12 1 0 9 40 12 25 \n",
"599 8/22/2020 12 1 0 3 40 12 25 \n",
"\n",
" Distance Travel Time \n",
"595 12.1 49 \n",
"596 12.1 40 \n",
"597 12.1 43 \n",
"598 12.1 49 \n",
"599 12.1 40 "
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.tail()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([25, 27, 28, 29, 30, 26], dtype=int64)"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data['Weather'].unique()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['Date', 'Time', 'Day', 'Special', 'Congestion', 'Drving Speed', 'Stops',\n",
" 'Weather', 'Distance', 'Travel Time'],\n",
" dtype='object')"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.columns"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"X = data.drop(['Date','Travel Time'],axis=1)\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"y = data['Travel Time']\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Train/test split\n",
"\n",
"1. split data into two parts \n",
"\n",
" training data set\n",
" testing data set\n",
"\n",
"2. Train the models on training set\n",
"\n",
"3. Test the models on testing data set"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"145 49\n",
"9 56\n",
"375 56\n",
"523 49\n",
"188 56\n",
" ..\n",
"71 40\n",
"106 73\n",
"270 56\n",
"435 34\n",
"102 56\n",
"Name: Travel Time, Length: 480, dtype: int64"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_train"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.linear_model import LinearRegression\n",
"from sklearn.svm import SVR\n",
"from sklearn.ensemble import RandomForestRegressor\n",
"from sklearn.ensemble import GradientBoostingClassifier\n",
"from sklearn.neural_network import MLPClassifier\n"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\Shiv\\AppData\\Roaming\\Python\\Python310\\site-packages\\sklearn\\neural_network\\_multilayer_perceptron.py:702: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (200) reached and the optimization hasn't converged yet.\n",
" warnings.warn(\n"
]
},
{
"data": {
"text/html": [
"<style>#sk-container-id-1 {color: black;background-color: white;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>MLPClassifier()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">MLPClassifier</label><div class=\"sk-toggleable__content\"><pre>MLPClassifier()</pre></div></div></div></div></div>"
],
"text/plain": [
"MLPClassifier()"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lr = LinearRegression()\n",
"NN = MLPClassifier()\n",
"lr.fit(X_train,y_train)\n",
"NN.fit(X_train,y_train)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"y_pred1 = lr.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"df1 = pd.DataFrame({'Actual':y_test, 'Lr Results':y_pred1})"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Actual</th>\n",
" <th>Lr Results</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>110</th>\n",
" <td>55</td>\n",
" <td>56.187653</td>\n",
" </tr>\n",
" <tr>\n",
" <th>419</th>\n",
" <td>56</td>\n",
" <td>55.732541</td>\n",
" </tr>\n",
" <tr>\n",
" <th>565</th>\n",
" <td>56</td>\n",
" <td>53.591764</td>\n",
" </tr>\n",
" <tr>\n",
" <th>77</th>\n",
" <td>55</td>\n",
" <td>56.690085</td>\n",
" </tr>\n",
" <tr>\n",
" <th>181</th>\n",
" <td>73</td>\n",
" <td>66.133304</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>399</th>\n",
" <td>56</td>\n",
" <td>54.599261</td>\n",
" </tr>\n",
" <tr>\n",
" <th>340</th>\n",
" <td>56</td>\n",
" <td>53.591764</td>\n",
" </tr>\n",
" <tr>\n",
" <th>148</th>\n",
" <td>49</td>\n",
" <td>52.322530</td>\n",
" </tr>\n",
" <tr>\n",
" <th>494</th>\n",
" <td>56</td>\n",
" <td>55.732541</td>\n",
" </tr>\n",
" <tr>\n",
" <th>439</th>\n",
" <td>43</td>\n",
" <td>38.662629</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>120 rows × 2 columns</p>\n",
"</div>"
],
"text/plain": [
" Actual Lr Results\n",
"110 55 56.187653\n",
"419 56 55.732541\n",
"565 56 53.591764\n",
"77 55 56.690085\n",
"181 73 66.133304\n",
".. ... ...\n",
"399 56 54.599261\n",
"340 56 53.591764\n",
"148 49 52.322530\n",
"494 56 55.732541\n",
"439 43 38.662629\n",
"\n",
"[120 rows x 2 columns]"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df1"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Actual</th>\n",
" <th>NN Results</th>\n",
" <th>LR Results</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>110</th>\n",
" <td>55</td>\n",
" <td>55</td>\n",
" <td>56.187653</td>\n",
" </tr>\n",
" <tr>\n",
" <th>419</th>\n",
" <td>56</td>\n",
" <td>56</td>\n",
" <td>55.732541</td>\n",
" </tr>\n",
" <tr>\n",
" <th>565</th>\n",
" <td>56</td>\n",
" <td>56</td>\n",
" <td>53.591764</td>\n",
" </tr>\n",
" <tr>\n",
" <th>77</th>\n",
" <td>55</td>\n",
" <td>55</td>\n",
" <td>56.690085</td>\n",
" </tr>\n",
" <tr>\n",
" <th>181</th>\n",
" <td>73</td>\n",
" <td>73</td>\n",
" <td>66.133304</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>399</th>\n",
" <td>56</td>\n",
" <td>56</td>\n",
" <td>54.599261</td>\n",
" </tr>\n",
" <tr>\n",
" <th>340</th>\n",
" <td>56</td>\n",
" <td>56</td>\n",
" <td>53.591764</td>\n",
" </tr>\n",
" <tr>\n",
" <th>148</th>\n",
" <td>49</td>\n",
" <td>49</td>\n",
" <td>52.322530</td>\n",
" </tr>\n",
" <tr>\n",
" <th>494</th>\n",
" <td>56</td>\n",
" <td>56</td>\n",
" <td>55.732541</td>\n",
" </tr>\n",
" <tr>\n",
" <th>439</th>\n",
" <td>43</td>\n",
" <td>43</td>\n",
" <td>38.662629</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>120 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" Actual NN Results LR Results\n",
"110 55 55 56.187653\n",
"419 56 56 55.732541\n",
"565 56 56 53.591764\n",
"77 55 55 56.690085\n",
"181 73 73 66.133304\n",
".. ... ... ...\n",
"399 56 56 54.599261\n",
"340 56 56 53.591764\n",
"148 49 49 52.322530\n",
"494 56 56 55.732541\n",
"439 43 43 38.662629\n",
"\n",
"[120 rows x 3 columns]"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_pred2 = NN.predict(X_test)\n",
"df2 = pd.DataFrame({'Actual':y_test, 'NN Results':y_pred2, 'LR Results':y_pred1})\n",
"df2"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x265e22fe0e0>"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAARAAAADTCAYAAABJAUy7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAABIYElEQVR4nO2dd3gU1frHP9s3vVdI6B2S0AlFQVCaIAgKCAqIIAgoIF5Fr4JeFa/+bHgBpSsqVVBAQCFU6S10QieBkAKkl63z+2NSCCSkZxM4n+fZJ7Nzzsy8M5v97inv+x6FJEkSAoFAUAKUtjZAIBBUXYSACASCEiMERCAQlBghIAKBoMQIAREIBCVGCIhAICgxQkAEAkGJUdvagHuxWq1ER0fj5OSEQqGwtTkCwSOJJEmkpKTg7++PUllwO6PSCUh0dDQBAQG2NkMgEABRUVFUr169wPJKJyBOTk6AbLizs7ONrREIHk2Sk5MJCAjI+T4WRKUTkOxui7OzsxAQgcDGFDaMIAZRBQJBiRECIhAISowQEIFAUGKEgFRR0gxmRCYGga0RAlIF2XTyJi3+s4W3Vp+wtSmCRxwhIFWMv0/HMHHZMQxmK+uOR5NuNNvaJMEjjBCQKsS2c7GM//UoZqvcdTGarfxz4ZaNrSp/JEniWGQCH64/zRNf7uC7sAu2NkmQRaXzAxHkz87z8YxdehSTRaJ3kB/u9lqW7r9G2Nk4nmria2vzyoXzsSmsC49m3fFoIu+k5+yPiE2xoVWCuxECUgXYe/EWY346jNFipUcTX74ZFML+y7dlATkXh9UqoVQ+HHFDUXfSWX8imnXh0ZyLuV8onPRq3unZ0AaWCfJDCEgl58Dl24z68TAGs5VujbyZNaQ5GpWStrU8cNSpuZVq4MSNJEICXG1taomJTzGw8eRN/gi/wdHIxJz9GpWCx+t74+Os45cDkQB82r8Z1d3sbWSp4F6EgFRiDl+9w8glh8gwWXi8vhezh7ZAq5aHrbRqJY/V92TjyRjCzsZWOQFJzjTx16kY1h2PZs/FW2QN66BQQGhtD/oG+9Ojqdw16/ntbgCea1mdPsH+tjJZkA9CQCopxyITGLH4EOlGCx3revLDiy3RqVV56nRt6MPGkzFsPRvHm081sJGlRSfTZCHsbBzrjt9ge0Q8RrM1pyw4wJW+wf48HeSHj7MekAdPx/18lJtJmdTydGBG3ya2Ml1QAEJAKiEnryfx0qKDpBrMtKvtzvyXWqHXqO6r17mBFwoFnL2ZzI3EDKq52tnA2gdjslj55+It1odH8/eZWFINudPO9bwd6RvsT59gf2p6Otx37LKDUWw+HYNGpWDW4OY46MS/a2VDfCKVjDPRyQxbeICUTDOta7qxcHhr7LT3iweAh6OOFoFuHLmWwLazsbwYWrNijS0Aq1Xi8LUE1h2/wcaTMdxJM+aUVXO1o0+wP8+E+NPQt+CkURdiU/how2kA3uregGbVXSrEdkHxEAJSiYiISWHYwgMkZZhoEejK4pFtCv3V7drImyPXEth6Ns6mAiJJEqejk1l/PJr1x6OJTsrMKfNw0PJ0kB99Q/xpEehWaIh4psnC68vDyTRZ6VTPk1c61i5v8wUlRAhIJeFiXApDF+znTpqRoOouLHm5DY5FaLJ3a+TD55sj2HfpNmkGc4U386/cSsvy1bjBpfi0nP1OOjXdm/rSN9if9nU8UKuK7rP4383nOHszGXcHLV8+F/zQTFE/jAgBqQRcjk9lyPwD3Eo10sTfmaUvt8VZrynSsfW8HQlwtyPqTga7L9zKmbkoT2KSMtlwQnbwOnE9KWe/Tq2kayNv+gb707mBd77jNoWx/Vwci/dcBeD/ngvCO2tAVVA5EQJiY67dTuOF+QeITzHQ0NeJn0e1xcW+aOIBcsaorg19WLL3KmFnY8tNQBLSjGw6FcMf4Tc4ePUO2YHAKqWCjnU96Rvsz1NNfHAqovDlR1xKJlNXHQdgRPuaPNHQ5/5KpgzQVL7B4kcVISA2JOpOOi/MP0BMcib1vB35+ZW2uDloi3awMQ1UOlCp6dZIFpDtEWXrlZpmMLP1bCx/hEez63x8TgwOQOuabvQN9qdXMz88HHWlvpbVKvHmyuPcTjPS0Ncp19s0/Q5c/Qeu7pb/xp2B5i/CM/8r9TUFpUcIiI2ITszghQX7uZGYQW0vB34Z3RbPonwRE6Ng+6dwfBkEDYJnf6BNLXecdGpupRoJv55Ii0C3EttlMFvYGRHPuuPRbD0bS6Yp11ejsZ8zz4T483Swf5lPGS/ac4XdF27hpU5nUbsM9GH/hiu7IfYUcE/eE+39U74C2yAExAbEJGUyZP5+ou5kUNPDnmWj2+HtVEhfP/0O7P4SDs4Hi0Hed2IFdH4brXttHqvvxZ8nb7LtbFyxBcRildh/+TbrwqPZdOomyZm5vho1PezpG1KNvsH+1PV2LO6tFk5mEteOboW/f2O99jRNlddQbL5HMBx9ITVG3q7WCrrNKHs7BCVCCEgFE5eSyQsL9nPtdjoB7nb8OrpdjudlvhjTYP9c2PMtGJLlfTU7yWMBNw7DoYXQ/RO6NvLmz5M32Xo2lqndC/dKlSSJ8KhE1h2PZsOJm8SnGHLKfJx19Anyp2+IP82quZTtAl+GFIg8AFd3wZXdSDfDqSFZeeXu8VaPelCzI9TqBAFtYc2rsoC4BMKQZWIMpBIhBKQCuZVqYOj8A1yOT6Oaqx2/vtIO/4K6AhYTHFsKOz6D1Fh5n08z+de3blc4/xcsGyTX6fIeXRp4o1TAuZgUriekFxhwVlCIvIudhl7N/Ogb7E+bWu6oymrq1JgGUQfk7sjV3XDjKEiWnGIFcMXqwwl1M7r2HIhjg87g7CcXShL8/hpc+we0TvDCCnD0Lhu7BGWCEJAKIiHNyLAFB7gQl4qvs55fR7clwD2fL7kkwZnfIew/cOeSvM+1Bjzxb2g6ELKXGaz3JLgGQmIknFqNW4uXaFnDjUNXE9h2Lo6X7nIqKyhE3l6r4snGPvQN9qdTPa+cQL1SYcqAqIOyWFzZDTeOgNWUt45rDajZiXB1M8b9Y0+MwoNfhrfFsY5n3nr/fAXHfwWFCp5fAj6NS2+foEwRAlIBJKWbGLbwAOdiUvB20vHr6LbU8MhnIPDyTtg6HaKPye/tPeHxf0HLkaC+Z3ZGqYJWo+T6B+dD8xfp2siHQ1dlr9SeTf0eGCLfN8Sfbo28sdeW8l/AlCl3pbJbGNcPgcWYt45zdbk7UrOT3DVxq8H1hHRe/HY3KZgZ37kO7e8Vj9NrIewjebvnf6Fut9LZKSgXhICUM8mZJl5adIDT0cl4Omr5dXRbanvdMxh58zhsnQGXtsnvtY4QOgHaTwDdA5YWbPES7JgJMSfg+iHa1KoHwK7z8bT+ZGtOtbtD5Hs29SuWn8l9mI1yq+LqbriySxYMc2beOk5+slhki4ZbTdmI7FNYrExaHk5KppmQAFcmdauf9/jrh2HtWHm77ThoM7rk9grKFSEg5UiqwczwRQc5fj0JN3sNv7zSjrredwnCncuw7RM4tVp+r9RAq5fhsbfA0avwC9i7Y27cH/WJZRxY8RkvJub9ogUHuPJMVoh8iT06LSa5RXRllywakQfAnJG3joN3rljUegzca+cRjHv53/aLHL6WgKNOzazBcoKkHBIjYdkQWZTqdYfun5TMbkGFIASknEg3mhm5+CDHIhNxsdPw8yttaeCbJR6pcbDzcziyGKxZU6bNnoMu74F7rULPfXeI/I0zQaxQLKN5yg6czQO5hRy12qaWOytfDS2+4Raz3CLKmiUhcj+Y0vLWsffMnSWp+Rh41nugYNzN4at3mJWVFPnjfk0J9LhrHCgzGX4dBGlx8oDxwIVyV01QaRECUg5kGC28vOQQh64m4KRX8/OotjTxd5G/IPv+B3v/l/ulrNMVuk0Hv+AHnrPgEPkanLarTxPOs7HTZS42GMsLCw5wKS4Vi1UqfDbFapG7QNljGNf2gfGeXKR2brJg1HxMFg2vhkUWjLtJyjDxxvJwrBL0b16Nfs2r5RZazLB6pOxp6ugLLyx/cPdNUCkQAlLGZJosjP7pMPsv38FRp+anl9vQzFcP+7+HXZ9D+m25on8LePJDuclfAA8Kkfd01NK7mRwi3zhhCvw+Fu+IX3F76l846dXcTjMSHpVIyxr3OJVZrbJ3Z/YsybW9YEjKW0fvAjU65nZLvBvnzv6UEEmSeHftSW4kZhDobs9HzzS5uxA2vw0Xt4LaThYPl+qlup6gYii2gNy4cYO3336bTZs2kZ6eTt26dVm8eDGtWrUC5H+U6dOnM3/+fBITE+nQoQNz586lXr16ZW58ZcNgtvDq0iP8c/EW9loVS0a0pHnC37DmY7lvD+BRF554Hxo/U+CveHaI/B/Hb3C5KCHy/v3h7/cg+QaaC5t5vH51Npy4SdjZWFoGuED82dwWxtV/IDMx7wV1zlCjfe7Ap0/TMu86rDpynT9P3EStVDBrSPO8QXcHfoBDCwAFDJgP/s3L9NqC8qNYApKQkECHDh3o0qULmzZtwsvLiwsXLuDmlvsr9/nnnzNr1ix+/PFHatWqxfvvv0/37t05c+YMev3DG5ptNFsZ/8tRdp6PR69RsObJNBpu7gexJ+UKjr7Q+R1oPgxU98+CFB4iX43ODbzyD5HX6OUZmX++hoPz6F/rLdxO/03o4fNwIiK31ZON1hECQ3NbGL5BoCq/xujl+FRmrJOzi01+sn7eBNDn/4K/psnbT34IjfqUmx2CskchFWOF5nfeeYc9e/awe/fufMslScLf358333yTqVOnApCUlISPjw9Llixh8ODB9x1jMBgwGHLdqJOTkwkICCApKQlnZ+fi3o9NMFmsTPj1KH+djqW1+hIL/DfgEndALtS5QMc35OlIbV7HscJC5J8J8efJxoWEyEsS3L4I4b/Kjlf5obGHwHZZfhidwD8kXxErDwxmCwPm7uXUjWRCa3vw8yttc8dlYk7Coh5gTJUFsM+sEo2tCMqe5ORkXFxcCv0eFutnZ926dXTv3p3nnnuOnTt3Uq1aNV577TVGj5anD69cuUJMTAzduuU6/bi4uNC2bVv27duXr4DMnDmTDz/8sDhmVCrMFiuTVoRz8cxRftCuorvyIMQhh9q3GQ2d3gR795z6DwqRb1PTnT4h/vRq6ltwiLwkydO/2WMYV//JDTS7ixPaEP5Kq0+T9j3p1f3p+x3RKogv/z7PqRvJuNpr+HpQSK54pMTIMy7GVHkcqPdXQjyqIMUSkMuXLzN37lymTJnCu+++y6FDh3j99dfRarUMHz6cmBj5H9nHJ28iGB8fn5yye5k2bRpTpkzJeZ/dAqkKWKwS//l1Kx0i5vCtdidqhRUUSgh+Qe6uuMr38aAQ+Sb+zvJyBg8KkU+4mncMI/lG3nKVDgLayFPCkftApeVw2++YvSWKTjGe9LKReOw6H8+8XZcB+HxAEL4uWV1YY5osHsk35MC553+qsBaRoGwploBYrVZatWrFp59+CkDz5s05deoU33//PcOHDy+RATqdDp2u9AlpKhprWgI7F7/LtPhV6NVZsR4NekHXD8C7kRwif/FWviHytTwd6BPsX3CIfGJUrlhc2Q1JkXnLlRqo3jprDKMjVG8jj4NYrTC7Ddy+wNOKXXxELfZfvk1KpqlUmcJKwq1UA1NWytnFhrULzF2/12qFta/CzXCwc4ehK+VpYkGVpFgC4ufnR+PGeQOaGjVqxG+//QaAr6/8TxIbG4ufn19OndjYWEJCQkppaiXBlIH1wDwyt3/BE5YUUMAdjxa4PzMTKaCtHCK//nSBIfLPhFSjaTXnvCHyydF3tTB2yy2Ou1GqoVrL3FiSgLb3jafI9ZTQ+hXY/DZeZ5dS030mV7NypfZq5nd//XJCkiT+tfoEt1IN1PN25L1ed/3PhH0IZ9eDSguDf5W9VgVVlmIJSIcOHYiIiMiz7/z589SoUQOAWrVq4evrS1hYWI5gJCcnc+DAAcaNG1c2FtsKixmOL0PaMRNl8g3sgQhrdRJCp+HevC+Ljt9k3fIdeULkXe019GyaT4h8SmyuWFzZnRt1m41CJU9lZrcwAtqBrojJfEKGQNhHKOLP8XL9G3xwx52tZ2MrVECW7L3KtnNxaNVKvnuhee66Nkd/gj3fyNvPzIYaJfCUFVQqiiUgkydPpn379nz66ac8//zzHDx4kHnz5jFv3jxATvA7adIkPv74Y+rVq5czjevv70+/fv3Kw/7yR5Lg3J9yZOitCBTADcmDr80DOeneA0WEmnM7c2el8g2RT42HM2tzc3veOp/3Ggql7ImaHUsS0Bb0JZyB0rtA0PNwZDG9MzfwAS+xIyK+aF6pZcDZm8nM3HgOgPd6NaKhb9Z9XN4JGybL24+/I9soqPIUS0Bat27N2rVrmTZtGh999BG1atXim2++YejQoTl1/vWvf5GWlsaYMWNITEykY8eObN68uWr6gNy+JEeFXj+Ys+ucNYCFlp6kSPb43N5PpqSluVpH0xp+PN4kkPYNq2OvMMKNf+Dv/XILI/7sPSdWgG8zWSxqdpR9Muxcy87uNqPhyGLco7ZQV/8MF9NcOBaZQKua7oUfWwoyjBYmLjuG0WKla0NvXgqVW6bEn4eVL8qDvE0HygPMgoeCYvmBVARFnX8mNQ7r1o+Q0m+jABQKCQVZv7A5t3TXreW5TangfXfvvxRWspuoaJRqudujUOa+7opnuS05odeocdBrc8tRZG0r8h6X56WQ6xX2HLP2x6ZkkpRuRK1UEOjhgFqB7MSWfiu3nksgqHX5Hn/feQv7fPLUpRh1Cz6vlL1Pyqc83/MW/mysPkGYhqy2WWCgJIFFkrBYJbQqZYFLpd5NufiBVCYuH91K7fCltjajcmA1A+YCiz0UKXJxavma4QP4ZIfM3C6g0r0zSpWM8ujkJV05QvvpG8ikcsw2zhrSnL7B/mVyriorIAkB3Vhg7snLqs0oFbLa/2bpyEFrI+De3437/y3u3idJd23nU8dBkUkrZQTtlGfxVSSU3U0Iqjypkp4YyZ1oyYNYyY2buBMruXNTcidOcsWAlmjJo9KIB8izZGVF1e3CAJtO3uTnFb/ymXIuAcp4JBSktRhDYug7WJV6zFYrVknCYkXetuY25bJfVknCbJWwZr03Z+2zWCU2HTzNC5HTaac8KzuJCSo1FkmBAS1G1BjRYESNQdJgRIMBtVwmqTGguatciwmV3A3GihIJJRJqhQVXUvFQJOOhSMaLJHQKU6E23GvPHZy4Lblg5+ZDpsadTK07GToPDFp3DDp3DDoPjDoPjHoPJI0DaqUCpVKBSglKhQKVUoFKkbUv6/3d26p76irv2p+9rb7rGHudqkjLpj70XRiAns388HIayaAf6zLRtJgh6u04Hv0Bx6id0P/7Ukd1xp7bS0fV6RIda5aUmFFhRI0ZFSbU8kuSt82oMaLCjBqTpMZE9v7suqqs/XnLjKgxS6p79svbRil324QaN1L4Svs9AG+bRnPCWjun7N5rWpQaUGpQqdSolAo0KgUalRKlQgGShBozeoURO4UBnWTK+msgMSlF3saIvcJIdUfoadpKY6s805SKHRsVj6GVDOgl+eutkwzoMaDHiB75nHqM2GHETmF80GN9ICqFhD0G7Mn1vylqnyRT0pCBjky0ZEhaDGjJQEuqZMctyYXj1EaFhAMZOCgycSAz5689megU93chVQoJL5LxUiRDUlThRmjswcETHLyyXp5ytrc877O27T3KNQCyqFTpFkg2F+NSGbH4IPWT9vC5dgGeJMoDi4/9CzpNKbGbtMUqcfnEXhSZCShVGlBrUKo0KNRaFCotSrUWpVqDQq1DqdIQk2YhPh20Wi06jRqdRoVWpUSnUaJTK9GqlKhVStQqBRql/FetVJTtuiv3smoEnF7LMnMXPpDGcPT9J8vMK/VoZALPfb8Pi1Xii4FBPNcqQE55+GMfefGr0AnFT0koSXI6Q1NG7sucvZ0uJ3E2pWfVSc/an9++7GPz25f1997kz1UKhRxjla/Y3CNCjt5yBHYx/s+K+j18KAQE5AWbXl5yiBs3rvOpdgk9lfvlAv/m0P8H8Cp8saWHkmt7YXFPMtHSJvN/zHzhMXoHld6pLCXTRK9Zu4m6k0GfYH9mDQ5BkXgN5neVZ10a9IZBSyt3SkKr5cEilUeA7t6XkVeQCt2XDpKNu8BqvSwoztWgx6eyZ/MDeCS6MHfj7aRn+ZhQxv9ylHHnJ/KMqhWf2/+ELvoY/PAYdJ0ObceWOrNWlSMwFLyboI87zXOqXYSdbVAmAvL+76eIupNBNVc7Pu7XFEVmEvzyvCwevkFyYqDKLB4g26dzLLqXb0mRJDk5dZ5WUmauuJSVSJky7094nY05U+5GJUXJTn2FCEhReWgEBMBRp2bB8Fa8u+Ykq44o2J/SkOU+P1Mrab+ctCZio+xC7VbD1qZWHAoFtHkFNkzmRdUWnj3Xp9ReqWuOXuf38GhUSgWzhoTgogV+GQG3IuQlHV5YIRbAvhuFQk6nUBFR0Var3H0sqMunUMo/KmXEQ/dzrFEp+XxgEG90rUcs7nSJncgqvzeRNA6yG/ncDnB06T1OPw85zZ5H0jlTUxlLM8NRjkaWfCr62u003v/9FABvdK1Hy0A32PgWXN4uDwK+sAKcy8bHQFAClEp57WB7dzmvrGdd8AuS0z3U7ix7P5dh6oSHTkBAjsmZ/GR9/jugGSqlkreutGSq52zM1dvKHprrJsCywXJQ26OAzhFFiBxu8KLqb7aeLdl9myxWXl8eTprRQpua7ozvUhf2zZaXp0ABAxYWml1e8HDxUApINoNaB7JgeCvstSp+u6KlX+q7pHT6QA4lP78Z5rSD07/b2syKofUrADyhDOf06RMlOsXXW85zPCoRZ72arweHoDq/Cf7+t1zY/RNo2KusrBVUER5qAQHo0sCbFWNC8XTUcSomjR6HmnNtwEY5mC3jDqwaDr+9AhkPuYepZ11MNTujVEh0TFzHtdtphR9zF3sv3mLuTjntwGcDgqiWHgG/jQIkeTW9dq+Vg9GCys5DLyAAzaq7sPa19tT2dOBGYgZ9Vt7hULfV8hKSCiWcXAVz2svrkjzEaNq9CsAg1Q62nyp6TMqdNCOTV4YjSTC4dQC9akhyF9CUDrW7QM/PRT7TR5RHQkAAAtzt+W1ce1rWcCM508zQxcf403MUjNoir9WSEg0/D5BzVhjKOerMVtTvToreDzdFKpnHVhXpEEmSePu3E8QmG6jt5cAH3QPlfKYpN+UV6p5bIvKZPsI8MgIC4Oag5ZdX2tK9iQ9Gi5Xxvx5lwRV3eHW37CMCcHgRfN9RXhP2YUOpwtR8BAAd7qwhOaNwT8yfD0Sy5UwsWpWSWc8HYb9+nLwUpr2nPONSlnlMBFWOR0pAAPQaFXOGtmR4VrKbj/88y0d/XcXa/TN46Q9wrg4JV+T1SrZ8AGZDIWesWrh3fAUjGpopr3B8/4PznUTEpPDxhjMA/KtHA5qe+VL2pVHpYMgycKtZARYLKjOPnICAvHDTjL5NmNazIQCL9lxhwrKjZAZ0gtf2QshQQII938K8LnCzZLMWlRIHT855PAmA/tiiAqtlmiy8vuwYBrOVx+t78bJ+h7wwOED/ubJfgeCR55EUEJB9RV59vA7fDg5Bo1Kw8WQMLy48QKLVDvrNkTOGO3hB3GmY/wTs+kJOrPwQoGwrLwQWnLwNc3JcvnVmbjxLRGwKno5avm2dgHKjvNIgXd6DpgMqylRBJeeRFZBsngmpxo8vt8FJr+bQ1QQGfr+P6wnp0LA3vLYfGj4NVhNs+xgWdYdbF21tcqlp2LIzp6iDFjM3t/9wX3nY2Vh+3HcNgDlP2eO64RWQLBA0SJ65EgiyeOQFBKB9HU9Wj22Pn4uei3Gp9J+zl1M3kuRQ6EE/y9G8Ohe4cVgeYD0wT445qKKoVUqO+z0HgPPpn+Wo1CzikjN5a7XcZZvY1oU2e8eCIVmOn+j7nZiuFeRBCEgWDXydWPNaexr6OhGfYmDQD/vYdT5e/sIED5bHRmp3lqMdN70FS/tB0nVbm11iXFsP5o7kiIsxRvbKBaxWiSkrj3MnzUiwr57Jt2dAYiS41YJBv9yVDFkgkBECchd+LnasHBtK+zoepBktvLzkEKuPZImES3UYthZ6/R+o7eDKTpgTCuG/VsnAvE6Nq7PK2gWAjD1y1rL5uy/zz8Vb6DUKfvb8EeX1Q/I6M0NXgYOHLc0VVFKEgNyDs17DkpFt6Bfij9kqMXXVcb4LuyAnolUq5TVXxu2R16Y1JMPv42DFMHnxqCqEs17Daf+BWCUFdlG7iDh1hC/+klcdXNVgJ04X/5Czug36GTzr2dhaQWVFCEg+aNVKvno+hHGd6wDw5ZbzvLv2JGZL1riHRx0YuVleSFupgXMb5MC8s+ttaHXxCW4WTJhVzht78vevMFslptc4SbOLcouEp7+Ww78FggIQAlIASqWCt3s05D/PNEGpgGUHoxiz9AjpxqypXJUaOr0JY7aDdxM5E9eKYfJKdhmJNrW9qHRr5M1Si+wT8pQpjP5OZxhx60u5sMMkaPGS7YwTVAmEgBTCi6E1+X5YS/QaJdvOxTF43n5upd7lnerbTBaRjpPlwLzjy2Bue7i03XZGF5EaHg7stjbjitUHZ0UGX5s+RmExQqM+cgpIgaAQhIAUgaea+PLr6Ha42Ws4cT2JZ+fs5cqtu8Lh1TroNkPu1rjVguQb8izNxrfAmG4rswsl6k46EkrWWTvk7vRvDv3nPXq5YwUlQvyXFJEWgW78Nq49ge72RN5J59k5e+5PDRjYVh5gzUrew8F5st9I1KGKN7gQzBYrbyw/hgYzTyiP5ha0fx209rYzTFClEAJSDGp7OfLbuPYEVXchId3EC/P38/fpmLyVtA7Q+0sYtgac/OHOJVj0FIR9BObKsw7JrLALHI1MYKZuMc2UV3MLzq6zmU2CqocQkGLi5aRj+Zh2PNHQm0yTlbE/H2Hpvqv3V6zbVXY+Cxokrwmy+0s5pibmVIXbfC8HLt/mf9svMka1gYGK7VhR8rlpkFx4dj0k37StgYIqgxCQEmCvVTPvxZYMaROAVYL3/zjNZ5vOYbXe41Bm5wbPzoPnfwI7d4g9CfM6wz9f53Efr0iS0k1MXhHOk4qDvKNZDsDZ4GnMsTzDCWVjsJrhyBKb2CaoeggBKSFqlZJP+zfjzSfrA/D9zktMWRmO0ZxPjEzjZ2D8AWjQSw7M2zoDFveE25cq1GZJknhnzQk8ks/wrXYOSiRoM4aAnpNRKxXMz3xCrnhkibwQkkBQCKUSkM8++wyFQsGkSZNy9mVmZjJ+/Hg8PDxwdHRkwIABxMY+nMsnKBQKJnatxxcDg1ArFfweHs2IxQdJzszny+foLacIeGYOaJ0g6oA8wHpoQYW5wq84FEX4qdMs1P4feoxQ90noPhNnvYa2td3ZbG1DutYDUmOqnFOcwDaUWEAOHTrEDz/8QFBQUJ79kydPZv369axatYqdO3cSHR3Ns88+W2pDKzPPtQpg0YjWOGhV7L10m+e/38fNpHyWGFQooPlQeWykZic5KfGfb8LPz0LSjXK18WJcKl+sP8Ii7Rd4KxLBuzEMXJSzwnvXhj6YULNR20M+4OD8crVH8HBQIgFJTU1l6NChzJ8/Hzc3t5z9SUlJLFy4kK+++oonnniCli1bsnjxYvbu3cv+/Q9hjtG7eKy+FyteDcXLSce5mBSenbOXiJiU/Cu7BsJL66DHZ/Kix5e2wdxQOLGyXFojBrOFSb8e5nO+pZEyEsnBW85nqs9dNLlbIx8AvrrTHkmhgsi9EHu6zG0RPFyUSEDGjx9P79696datW579R44cwWQy5dnfsGFDAgMD2bdvX77nMhgMJCcn53lVVZpWk5ePqOPlwM2kTAZ+v5d9l27nX1mphHbj5ITO/i0gMwnWjIaVL0HarTK16/PNETx7ay5dVceQVHoUQ5bLInYXgR721PN2JNrqRrRfV3mnaIUICqHYArJ8+XKOHj3KzJkz7yuLiYlBq9Xi6uqaZ7+Pjw8xMTH31QeYOXMmLi4uOa+AgIDimlSpqO4mLx/RuqYbKZlmhi86yB/hD+ieeNWXl5bo8m85+vXsOjkw79zGMrFnR0Qcxn0/8LJazvmhePYHqJ7/yuxds1ohq1VZK8ydWFFl4noEtqFYAhIVFcUbb7zBL7/8gl6vLxMDpk2bRlJSUs4rKiqqTM5rS1zttSwd1ZZezXwxWqy8sTycH3ZeklMC5IdKDY+/Ba+EgVcjSIuH5UPg9/GQWfIWWXyKgd9WLGGG+kd5R9cPoEm/Aut3a+QNwIIoPySvhvIYzfFlJb6+4OGnWAJy5MgR4uLiaNGiBWq1GrVazc6dO5k1axZqtRofHx+MRiOJiYl5jouNjcXX1zffc+p0OpydnfO8Hgb0GhX/G9KClzvUAmDmpnN8uP4Mlnt9Re7GPwTG7ID2EwEFhP8MczvAlV3Fvr7VKvH1L7/zqeUrVAoJc9AQ6Djlgcc0D3TD3UFLSqaFy7VekHceWlCl0zcKypdiCUjXrl05efIk4eHhOa9WrVoxdOjQnG2NRkNYWO56IxEREURGRhIaGlrmxld2lEoFH/RpzL97N0KhgCV7r/LaL0fIND3AiUyjh6c+hpEbwbUGJEXCj31g0ztgymdmpwCWbTvEazffxUmRQbp/O9R9ZxWaz1SlVNC5gRcAq03t5enm2xfhyo4iX1fwaFEsAXFycqJp06Z5Xg4ODnh4eNC0aVNcXFwYNWoUU6ZMYfv27Rw5coSRI0cSGhpKu3btyuseKj2vdKrN/4a0QKtS8tfpWIYuOEBCWiFxMTXay4F5LUfI7w/MhR8egxtHCr3e6WuxNN01luqKWyTb18B+2DJQa4tka/ZszKbzqUghQ+SdYjBVUABl7on69ddf8/TTTzNgwAAee+wxfH19WbNmTVlfpsrRO8iPpaPa4KxXc+RaAgPm7iXqTiGh/jon6PMtDF0Njr5w6zwseBK2fVKgp2i6wUj80pEEKy+RqnTC6eU1YO9eZDs71fNEo1Jw9XY6UXWHyjvPb5aTKwsE96CQChzZsw3Jycm4uLiQlJT00IyH3M2F2BRGLD7EjcQMPB11LB7RmmbVXQo/MP0ObJwKp36T3/sFy8tNeDfKU237nAl0iVuKCTUZg1fj3LBLsW18ceEBdl+4xbu9GjLmymQ5gXTHyXLOE8EjQVG/hyIWpoKp5yMvH9HIz5lbqQYGzdvH9oj8V4fLg7277Dk6cLEcpHfzOPzwOOyZlROYd3z9bLrELQXgauinJRIPgK4N5dmYrWfjoM0YeefRn8CUWaLzCR5ehIDYAB9nPStfbUenep6kGy288uNhVhwqYheh6bPyinn1ngKLAba8D0ueJmHPYhofeR+AvdVGUq/7qyW2L9sf5Mi1BBIDnpAXHE+/DafXlvicgocTISA2wkmvYdGI1jzbohoWq8Tbv53k6y3nC/YVyXOwL7ywEvrMAq0jRO7FbcskNFj4R9eR1iP/r1S2Bbjb08DHCYtVYseFBGg1Ui44JAZTBXkRAmJDNColXz4XzMQn6gLwbdgF3v7tBCZLEfwuFApoORyG542abeUloUkv/Ro1XRtld2NiocVwUGnlGaAbRws5UvAoIQTExigUCt58qgGf9G+KUgErD1/nlR8Pk2YwF36w2UjKurfz7NJf3yO7wp9cXSq7srsxO8/HY7LzgCb95YJDC0p1XsHDhRCQSsLQtjWY/1Ir7DQqdp6PZ9C8fcSlPGDQUpIw/j4Rp9iDpEh2fFZrEbx2QJ6dyUyE30bBqpHy7E0JCAlwxcNBS0qmmUNX7kDr0XLBydWQVkCAoOCRQwhIJaJrIx+WjWmHh4OWUzeSeXbOXi7Fp+ZbV9r9FdpTyzFLSmbo32L8oL7g3VCOp3n8bVCo4PQauTVy/u9i26JSKuhy92xM9VayOFkMcGxpqe5T8PAgBKSSERLgyprX2lPTw57rCRkMmLuXw1fvaUWcXoti20cAfGgZwdChL+Ok18hlKg10eRde2QKe9SE1Fn59Dta9DoYC8pMUQHZwXdi5WCTIbYUcXmiznK6CyoUQkEpIDQ8HfhvXnpAAVxLTTQxdcIDNp7IypV8/jHXNWAAWmXvg23U8LQLd7j9JtZbw6i5oNx5QwNEf5cC8q3uKbEfHel5oVUqu3U6XW0LNBso+KImRcKH4rRrBw4cQkEqKh6OOZaPb0a2RDwazlXG/HGX11n+Qlg1GackkzNKcLQETGft4nYJPorGDHp/KMzUugZB4DZb0hr/eK5JTmKNOTdvashv81rNx8vmaD5MLRXyMACEglRo7rYrvh7VgWLtAHKR0mu4aiyItnjPWGryvnsxXg1uiUj44whaAWp3kwLzmwwAJ9v0P5j0O0ccKPTQ7uC7sbFZi7FajAAVcCqvwrPKCyocQkEqOWqXkP30a8qf/Ihoqo4iVXBllnMq0fq3xc7Er+on0zvDMbBiyHBy8If4cLOgGO/77wCUcsv1BjlxLkCOI3WvJXrAAhxaW5tYEDwFCQCo7koRi8zvUuLOXdEnHKONUbuLBz/uvkZRRgrVbGvSUXeEbPyMvIrXjU1j4JMRH5Fu9ups9DX2dsErkxuy0yRpMPfYzGNPyPU7waCAEpLJz4Ac4tAArCiabXuOUVBu1UsGBK3d47vu9RCcWPclQDg4e8NyP8OwC0LvIXZkfHoN9c/LNPpbdCgk7myUgdbqCWy0wJMHJVaW5O0EVRwhIZSZiM/w1DYDPTIPZrmzLpjc6sX5iR3ycdZyPTaX/nD2cvVmCvKkKBQQ9J7dG6nQFc6Z8rZ/6QsK1PFXv9ko1mq1yRvnWo+TCgxW3MJag8iEEpLIScxJWvwySlZXWJ5hneZppPRvSyM+ZRn7OrH2tA/V9HIlNNvD89/vYc7GES0E4+8Ow36D3V6Cxh6u75eneo0tzhCGkuiuejlpSDWYOXsnySQkZCmo7eb3fqANldNOCqoYQkMpISgz8OghMaRxTBfGucQRdGngzon3NnCr+rnasGtuetrXcSTGYGbH4IGuPXS/Z9RQKuUUxbg8EtANjCqybAMsGQ0osSqWCLg3uCq4DOT9Js4Hy9sF5pbhZQVVGCEhlw5gmi0fyDeJ0NRieNgFXRwe+eC4YxT1JkV3sNPw0qg19gv0xWSQmrzjOnB0Xi5YSID/ca8vJnLt9KEffnt8su8Kf/j2nGxN2Ljb3/NmDqWfWQcrDuf6x4MEIAalMWK2wZgzcDMeodWVg8iSSceSr54PxdNTle4hOreLbQSG8+lhtQF6F7v0/Tj14+YgHoVRBx0ny8hI+zSDjDqwaTrez7+GpSifqTgYX4rLic/yCIaAtWE2yp6vgkUMISGUibAac24Ck0jLGNIVIyYcxj9XmsfpeDzxMqVQwrVcjZvRpjEIBP++P5NWlR8gwliJexacJjN4GnaaCQon69Gr+1r/DY8rjubMxcFd8zKIH+pMIHk6EgFQWjv4Ee74FYLbTZHZk1KVpNWemPtWgyKcY0aEWc4e2QKdWsvVsLEPm7+d2qqHkNqm10PV9ePlvcK+Du+UWP2n/S+0D/wZDViukcV9w8IKUm3Duz5JfS1AlEQJSGbi8EzZMBuBQjTH8X0ww9loVswY3R6su3kfUo6kfv7zSFld7DeFRiQyYu5drt0vp7BXQGsb+Q2qIPHXbPWMjlrkdIHI/qHVyxjIQyYYeQYSA2Jr487DyRbCaSajdlyEXOgMwo28Tans5luiUrWq6s3pse6q72XH1djrPztnL8ajE0tmptcex31dMc/yYG5IHqsSrsKgHbPkAmg+V849c3Q1xZ0t3HUGVQgiILUm7LefqyEzCUq0Nz90chtkqL0L1XMvqpTp1XW9H1rzWnqbVnLmdZmTwvP25AXGlwDPoKXoY/ss+p+6AJHe7lg8Dj6yoYBGl+0ghBMRWmA2wYigkXAXXGsywf4+LCWaqudrxaf9m903ZlgRvJz0rxoTyeH0vMkwWRv90mF8PlG6Fua6NfEjBntHJozA99zPYe0LcaXnVPIATKyCzBJ6xgiqJEBBbIEmwbiJE7gOdC2HNv2PpyTSUCvh2cAgudpoyu5SDTs2C4a14vlV1rBK8u/YkX/4dUWJfkaBqLng56Ug1mNmvbSe7wjd8OreCMRWOLy8j6wWVHSEgtmDXF/IvtUJFbI95vLFNTu7zetd6tKpZ9HVsi4pGpeS/A4KY1K0eAN9tu8jUVUVcPuIelEoFTzS4K7jO0QsG/Qz9vgdd1hKI5zeXme2Cyo3a1gY8cpxcDds/AcDc60te3etEqiGR1jXdmNClbrldVqFQMKlbffxc9Ly79hS/Hb1OXEomc4a2yM2nWgQsFgtPNnDjn4hoTlyLJyMjQ+5uNewP1ULlEP+ANpAplsGszGg0GlQqVanPIxbXrkgiD8CPfeTM5qET+IIXmb39Ek56NZve6ER1N/sKMWN7RBzjfzlKutFCYz9nFo9sjY+z/oHHSJJETEwMiYmJWCWJm0mZSBL4OOvQqERDtiri6uqKr69vvuNtRf0eihZIRZFwFZa/IItHg97sq/0GcxYdAuCzZ4MqTDwAujTwZsWYUEYuOcSZm/LyET++3Jq63k4FHpMtHt7e3tjb26NLzCDNYMbDUYdHAW72gsqJJEmkp6cTFyd7FPv5+ZX4XEJAKoKMRPjleUi/Bb5BJPSYzeS5R5EkGNQqgN5BJf8AS0qz6i6sfa09wxcf5HJ8Gs/O2cuC4a1pU+v+MRiLxZIjHh4eHgC4WZSkWzLIsKrQ6x/cehFUPuzs5HSYcXFxeHt7l7g7I9qe5Y3FBKtGwK0IcPJHGrKct9dfIiY5k9qeDkzv29hmpgW42/Pb2Pa0rOFGcqaZYQsP8OeJm/fVM5nkGBd7+9xWUva4SbrRXKLBWIHtyf48sz/fkiAEpDyRJNj4FlzeLifreWE5v54z8/eZWDQqBbOGNMdea9tGoJuDll9eaUv3Jj4YzVYmLDvKgt2X8617d19Zq1Zip5F/tVIyi7COr6DSURa+RsUSkJkzZ9K6dWucnJzw9vamX79+RETkTcabmZnJ+PHj8fDwwNHRkQEDBhAb+4jmitg3G44sBhQwYCEXlLX5z4YzALzdoyFNq7nY1r4s9BoVc4a2ZET7mkgSfPznWT5afwZrISkBslshKZkiCvdRpVgCsnPnTsaPH8/+/fvZsmULJpOJp556irS03GCtyZMns379elatWsXOnTuJjo7m2WefLXPDKz3n/oS//y1vd/+EzDrdmbjsGJkmK53qefJyh1q2te8eVEoF0/s05t1eDQFYtOdKlr0FpwRwtpNbTymZZqyVazJPUFFIpSAuLk4CpJ07d0qSJEmJiYmSRqORVq1alVPn7NmzEiDt27evSOdMSkqSACkpKak0ptmWG8ck6WNfSZruLEnrJ0mS1SpN/+OUVOPtDVKLj/6WYpMzbG3hA/kj/IZU792NUo23N0jPzd0rxd5Jks6cOSNlZOS122q1Sqejk6TjUQlScobRRtZWXQBp7dq1Nrt+RkZGvp+rJBX9e1iqMZCkpCQA3N3lkfsjR45gMpno1q1bTp2GDRsSGBjIvn378j2HwWAgOTk5z6tKkxwt5xI1pUOdJ6Dn52yLiGPJ3qsA/N9zwXg7Ve5Zi77B/vz4chuc9GoOXr3DG8vDMeez3INCocBZL7dCkiv5OMi+fftQqVT07t27WMfVrFmTb775pnyMeggosYBYrVYmTZpEhw4daNq0KSD7Cmi1WlxdXfPU9fHxISYmJt/zzJw5ExcXl5xXQEBASU2yPYZUOZ9pyk3wagjPLSEuzcLUVScAGNmhJl0aetvYyKIRWseD1WPb4+eiJ/JOOvEpRjKN94uEc/Y4SIap5LlYK4CFCxcyceJEdu3aRXR0tK3NeWgosYCMHz+eU6dOsXx56QKnpk2bRlJSUs4rKiqqVOezGVYLrBkNMSfkCNUXVmDVOvPmquPcSTPSyM+Zd3o2tLWVxaKBrxNrX+tALU8HLFaJyISMnAFTSZJIN5pRKsBotpKcaeJOmpF0o7lcXyURqdTUVFasWMG4cePo3bs3S5YsyVO+fv16WrdujV6vx9PTk/79+wPQuXNnrl27xuTJk1EoFDmzFjNmzCAkJCTPOb755htq1qyZ8/7QoUM8+eSTeHp64uLiwuOPP87Ro0eLbXtlp0RziBMmTGDDhg3s2rWL6tVz81b4+vpiNBpJTEzM0wqJjY3F19c333PpdDp0uofAk3HLBxCxEVQ6GLIM3GqyYNcldl+4hV6j5LshIejUpY89qGh8XfR8MziEsxGXkCSJq7fSqeZmh16jpPEHf1W4PWc+6l7sqe+VK1fSsGFDGjRowLBhw5g0aRLTpk1DoVDw559/0r9/f9577z1++uknjEYjGzduBGDNmjUEBwczZswYRo8eXaxrpqSkMHz4cL777jskSeLLL7+kV69eXLhwASengj1+qxrF+iQkSWLixImsXbuWHTt2UKtW3pmEli1botFoCAsLY8CAAQBEREQQGRlJaGho2Vld2Ti8SF7xHqD/XAhow8nrSXzxlzzF/cHTTR7oJl7ZcdRp8HDUotdrSDVLXE9Iz+m6VAUWLlzIsGHDAOjRowdJSUns3LmTzp0788knnzB48GA+/PDDnPrBwcGAPLanUqlwcnIq8AewIJ544ok87+fNm4erqys7d+7k6aefLuCoqkexBGT8+PH8+uuv/PHHHzg5OeWMa7i4uGBnZ4eLiwujRo1iypQpuLu74+zszMSJEwkNDaVdu3blcgM259I2+HOqvN3l39B0AGkGM68vP4bJItGjiS9D2lThcZ0sFAoFfi56Eo0Qn2IgKcPIlsmP4e+qx2yRiIhNAeRuT3kG12U7rxWViIgIDh48yNq1awFQq9UMGjSIhQsX0rlzZ8LDw4vduigKsbGx/Pvf/2bHjh3ExcVhsVhIT08nMrJ0CZ0qG8USkLlz5wJy3/BuFi9ezIgRIwD4+uuvUSqVDBgwAIPBQPfu3ZkzZ06ZGFvpiDsHK4eDZIGgwfCYLCQfrj/NlVtp+Lno+WxA2WQXqwxki4hWpSQ6MYMMk4X4FCMB7va42WvJMFmwWMHFrvKEWC1cuBCz2Yy/v3/OPkmS0Ol0/O9//8uJCSkOSqXyvrGYe93Bhw8fzu3bt/n222+pUaMGOp2O0NBQjEZjyW6kklLsLkxh6PV6Zs+ezezZs0tsVJUgNV7OZ2pIhsBQ6DsLFAo2nIhm5eHrKBTw9aAQXO21tra0zPFw1KFWKYm6k05ypokrt1Kx16rIMFlIyTTh7lA57tlsNvPTTz/x5Zdf8tRTT+Up69evH8uWLSMoKIiwsDBGjhyZ7zm0Wi0WS15nOi8vL2JiYpAkKefHITw8PE+dPXv2MGfOHHr16gVAVFQUt26VcP3iSkzl+amoSpgy5dD8xEhwqwWDfgG1jqg76UxbcxKACV3q0q62h40NLT9c7DSoPR24djuddKOFDJPsJ5KSacZqlVAqbd/q2rBhAwkJCYwaNQoXl7xhAwMGDGDhwoV88cUXdO3alTp16jB48GDMZjMbN27k7bffBmQ/kF27djF48GB0Oh2enp507tyZ+Ph4Pv/8cwYOHMjmzZvZtGlTnrwZ9erVY+nSpbRq1Yrk5GTeeuutErV2KjsimK64SBL88RpcPwh6Fxi6Chw8MFusTF4RTkqmmeaBrrzetZ6tLS13HHRq6ng5oFXnNumtkkRaPv4itmDhwoV069btPvEAWUAOHz6Mu7s7q1atYt26dYSEhPDEE09w8ODBnHofffQRV69epU6dOnh5ySsENmrUiDlz5jB79myCg4M5ePAgU6dOve/aCQkJtGjRghdffJHXX38db++q4QNUHERGsuKy/VPY+V9QquHFtVDrMQC+3nKeb8Mu4KiTs4sFuFdcgqDyJjMzkytXrlCrVq18c3+YLFau3U4jPWspTQ8HHdXcHr5f24eNB32uRf0eihZIcTi+QhYPgKe/yRGPg1fu8N22CwB80r/pQyUeRUGjUlLL0zFnatdgLsWavIIqhRgDKSrX9sK6CfJ2h0nQ4kUAktJNTFp+DKsEz7aoxjMh1Wxnow1RKRXU8LAnMcNU7KlWQdVFCEhRuH0Jlg8FixEa9YGu0wF5VurdtSeJTsqkhoc9Hz3T1MaG2haFQoHbQzjrJCgY0YUpjIwEOUAu4w74N4f+80ApP7ZVh6/z58mbqJUKZg1ujqNO6LHg0UIIyIMwG2HFi3D7AjhXhyHLQSuPb1yKT2X6utMAvPlUA4IDXG1oqEBgG4SAFIQkwZ9T5BXntY7wwgpwkuMhDGYLry87RobJQvs6Hrz6WG0bGysQ2AYhIAWx51s4thQUShi4CHxzxzf+768ITkcn42av4etBIZXCaUogsAVCQPLjzDrYKg+U0uMzqN89p2jn+Xjm774CwBcDgwtd0U0geJgRAnIvN47CmjHydpsx0PbVnKJbqQbeXHkcgJdCa9CtsY8tLBQ8ouSXyMjWCAG5m6Trcj5TcwbUfRK6z8wpkiSJqauOcyvVQAMfJ97t1ciGhgqKyogRI+jXr1+pz9O5c+ecrGR6vZ769eszc+ZMm6ZxLKt7Kw1CQLIxpMjTtamx4N1YHvdQ5U7LLt5zlR0R8WjVSmYNaY5eOEs9lDxolbbRo0dz8+ZNIiIimDZtGh988AHff/99BVpX+RACAnI+09WjIPYUOHjLMy76XP//M9HJfLbpHAD/7t2IBr5VN7uYIC8KhYK5c+fSt29fHBwc+OSTTwqsa29vj6+vLzVq1GDkyJEEBQWxZcuWnHKDwcDUqVOpVq0aDg4OtG3blh07duSUX7t2jT59+uDm5oaDgwNNmjTJSZ+4ZMmS+5KR//777wXmkpkxYwY//vgjf/zxR07LaMeOHRiNRiZMmICfnx96vZ4aNWowc+bMfM9RFgjPJ4C/3oMLf4FaL/t6uAbmFGUYLUxcdhSjxUq3Rj682K6GDQ2tREiSvHRFRaOxhzJO0DRjxgw+++wzvvnmG9Tqwr8SkiTxzz//cO7cOerVy426njBhAmfOnGH58uX4+/uzdu1aevTowcmTJ6lXrx7jx4/HaDSya9cuHBwcOHPmDI6OjiWyeerUqZw9e5bk5GQWL14MyCkYZ82axbp161i5ciWBgYFERUWVa6JyISAH58MBOdMa/X+A6i3zFH+04QyX4tPwdtLx+cCghya7WKkxpcOn/oXXK2vejQatQ5me8oUXXigwodDdzJkzhwULFmA0GjGZTOj1el5//XUAIiMjWbx4MZGRkTnZz6ZOncrmzZtZvHgxn376KZGRkQwYMIBmzZoBULt2yf2HHB0dsbOzw2Aw5MnXGhkZSb169ejYsSMKhYIaNcr3B+/RFpALW2HTv+TtrtOhSb88xZtP3WTZwcic7GKVJdOWoGxp1apVkeoNHTqU9957j4SEBKZPn0779u1p3749ACdPnsRisVC/fv08xxgMBjw85MRSr7/+OuPGjePvv/+mW7duDBgwgKCgoDK9lxEjRvDkk0/SoEEDevTowdNPP31fNray5NEVkIwEWP0ySFYIGQYdJ+cpjk7M4O3f5Oxirz5Whw51PW1hZeVFYy+3Bmxx3TLGwaFoLRoXFxfq1q0LyEtF1K1bl3bt2tGtWzdSU1NRqVQcOXIElSrvAHt2N+WVV16he/fu/Pnnn/z999/MnDmTL7/8kokTJxYpz2pRaNGiBVeuXGHTpk1s3bqV559/nm7durF69epin6soPLoCYucG/WbD0Z/g6a/z9KstVonJK8JJyjARXN2FN5+q/4ATPaIoFGXelahKODo68sYbbzB16lSOHTtG8+bNsVgsxMXF0alTpwKPCwgIYOzYsYwdO5Zp06Yxf/58Jk6ciJeXFykpKaSlpeUI2r15Vu8lv3ytAM7OzgwaNIhBgwYxcOBAevTowZ07d3KWoC1LHl0BATk0v+HT9w3Kzd1xkQNX7uCgVfHt4OblukyBoPxJSkq678vo4eFR6mVUX331Vf7zn//w22+/MXDgQIYOHcpLL73El19+SfPmzYmPjycsLIygoCB69+7NpEmT6NmzJ/Xr1ychIYHt27fTqJHsT9S2bVvs7e159913ef311zlw4MB9K+jdS82aNfnrr7+IiIjAw8MDFxcXvvvuO/z8/GjevDlKpZJVq1bh6+t73wxPWSG+GfeIx5FrCXy9Vc4u9tEzTanp+ej+yj4s7Nixg+bNm+d53b2QVElxd3fnpZdeYsaMGVitVhYvXsxLL73Em2++SYMGDejXrx+HDh0iMFCe1bNYLIwfP55GjRrRo0cP6tevn7Pkibu7Oz///DMbN26kWbNmLFu2jBkzZjzw+qNHj6ZBgwa0atUKLy8v9uzZg5OTE59//jmtWrWidevWXL16lY0bN6JUls9XXeREvfvamSZ6fbub6wkZ9A3259vBIWLWhcJzogqqJiInahkiSRLv/36K6wkZVHez4+P+TYV4CASFIAQkizVHb/BHeDQqpYJvBzevUmu/CgS2QggIcPVWGh/8cQqASV3r0bKGm40tEgiqBo+8gBjNVt5Yfow0o4W2tdx5rUtdW5skEFQZHnkB+WrLeY5fT8LFTs4uphLZxQSCIvNIC8iei7f4YdclAP47oBn+rmI1tQdhtVptbYKgDCmLz/ORdSRLyjAxeUU4kgRD2gTSo6mfrU2qtGi1WpRKJdHR0Xh5eaHVasUMVRVGkiSMRiPx8fEolUq02pLHeD2yAuKsVzOxaz1WHIrkg6cb29qcSo1SqaRWrVrcvHmT6GgbxL8IygV7e3sCAwNL5WT2yDuSWaySGPcoIpIkYTab842/EFQtVCoVarW6wJZkUb+H5dYCmT17Nl988QUxMTEEBwfz3Xff0aZNm/K6XIkR4lF0FAoFGo0GjUb4yAhkymUQdcWKFUyZMoXp06dz9OhRgoOD6d69O3FxceVxOYFAYCPKRUC++uorRo8ezciRI2ncuDHff/899vb2LFq0qDwuJxAIbESZC4jRaOTIkSN069Yt9yJKJd26dWPfvn331TcYDCQnJ+d5CQSCqkGZj4HcunULi8WCj0/eRZd8fHw4d+7cffVnzpyZb2i1EBKBwHZkf/8Km2Ox+TTutGnTmDJlSs77Gzdu0Lhx41InexEIBKUnJSUFFxeXAsvLXEA8PT1RqVTExsbm2R8bG5sne3Q2Op0OnU6X897R0ZGoqCicnJzum2JKTk4mICCAqKioCs8VUpUQz6loiOdUMJIkkZKSkpNhviDKXEC0Wi0tW7YkLCwsZ9k9q9VKWFgYEyZMKPR4pVJJ9erVH1jH2dlZfOBFQDynoiGeU/48qOWRTbl0YaZMmcLw4cNp1aoVbdq04ZtvviEtLa1Ia28IBIKqQ7kIyKBBg4iPj+eDDz4gJiaGkJAQNm/efN/AqkAgqNqU2yDqhAkTitRlKQ46nY7p06fnGTMR3I94TkVDPKfSU+liYQQCQdXhkc4HIhAISocQEIFAUGKEgAgEghIjBEQgEJQYISACgaDEVBkBmT17NjVr1kSv19O2bVsOHjxoa5MqlJkzZ9K6dWucnJzw9vamX79+RERE5KmTmZnJ+PHj8fDwwNHRkQEDBtwXUhAZGUnv3r2xt7fH29ubt956C7PZXJG3UmF89tlnKBQKJk2alLNPPKMyRqoCLF++XNJqtdKiRYuk06dPS6NHj5ZcXV2l2NhYW5tWYXTv3l1avHixdOrUKSk8PFzq1auXFBgYKKWmpubUGTt2rBQQECCFhYVJhw8fltq1aye1b98+p9xsNktNmzaVunXrJh07dkzauHGj5OnpKU2bNs0Wt1SuHDx4UKpZs6YUFBQkvfHGGzn7xTMqW6qEgLRp00YaP358znuLxSL5+/tLM2fOtKFVtiUuLk4CpJ07d0qSJEmJiYmSRqORVq1alVPn7NmzEiDt27dPkiRJ2rhxo6RUKqWYmJicOnPnzpWcnZ0lg8FQsTdQjqSkpEj16tWTtmzZIj3++OM5AiKeUdlT6bswxU1Q9KiQlJQEgLu7OwBHjhzBZDLleU4NGzYkMDAw5znt27ePZs2a5Qkp6N69O8nJyZw+fboCrS9fxo8fT+/evfM8CxDPqDyweT6QwihugqJHAavVyqRJk+jQoQNNmzYFICYmBq1Wi6ura566Pj4+xMTE5NTJ7zlmlz0MLF++nKNHj3Lo0KH7ysQzKnsqvYAI7mf8+PGcOnWKf/75x9amVCqioqJ444032LJlC3q93tbmPBJU+i5McRMUPexMmDCBDRs2sH379jx5U3x9fTEajSQmJuapf/dz8vX1zfc5ZpdVdY4cOUJcXBwtWrRArVajVqvZuXMns2bNQq1W4+Pj88g/o7Km0gvI3QmKsslOUBQaGmpDyyoWSZKYMGECa9euZdu2bdSqVStPecuWLdFoNHmeU0REBJGRkTnPKTQ0lJMnT+ZZXmPLli04OzvTuHHVX52va9eunDx5kvDw8JxXq1atGDp0aM72o/6Myhxbj+IWheXLl0s6nU5asmSJdObMGWnMmDGSq6trnpHyh51x48ZJLi4u0o4dO6SbN2/mvNLT03PqjB07VgoMDJS2bdsmHT58WAoNDZVCQ0NzyrOnKJ966ikpPDxc2rx5s+Tl5fVQT1HePQsjSeIZlTVVQkAkSZK+++47KTAwUNJqtVKbNm2k/fv329qkCgXI97V48eKcOhkZGdJrr70mubm5Sfb29lL//v2lmzdv5jnP1atXpZ49e0p2dnaSp6en9Oabb0omk6mC76biuFdAxDMqW0Q+EIFAUGIq/RiIQCCovAgBEQgEJUYIiEAgKDFCQAQCQYkRAiIQCEqMEBCBQFBihIAIBIISIwREIBCUGCEgAoGgxAgBEQgEJUYIiEAgKDH/D5gXNffyJqV5AAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.subplot(221)\n",
"plt.plot(df1['Actual'].iloc[0:11],label='Actual')\n",
"plt.plot(df1['Lr Results'].iloc[0:11],label='Lr Results')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\tTime\tDay\tRush\tSpecial\tCongestion\tDrving Speed\tStops\tWeather\tDistance\tTravel Time"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x265e2510ca0>"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.subplot(221)\n",
"plt.plot(df1['Actual'].iloc[0:11],label='Actual')\n",
"plt.plot(df2['NN Results'].iloc[0:11],label='NN Results')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Prediction with Current parameters (Predict Time with trained Model)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Time</th>\n",
" <th>Day</th>\n",
" <th>Special</th>\n",
" <th>Congestion</th>\n",
" <th>Drving Speed</th>\n",
" <th>Stops</th>\n",
" <th>Weather</th>\n",
" <th>Distance</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>6</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>8</td>\n",
" <td>40</td>\n",
" <td>14</td>\n",
" <td>23</td>\n",
" <td>14.7</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Time Day Special Congestion Drving Speed Stops Weather Distance\n",
"0 6 1 0 8 40 14 23 14.7"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = {'Time':6,\n",
" 'Day':1,\n",
" 'Special':0,\n",
" 'Congestion':8,\n",
" 'Drving Speed':40,\n",
" 'Stops':14,\n",
" 'Weather':23,\n",
" 'Distance':14.7\n",
" }\n",
"df = pd.DataFrame(data,index=[0])\n",
"df\n"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"linear regression [61.09983093]\n",
"Neural Network [55]\n",
"Actual Travel Time :- 58\n"
]
}
],
"source": [
"new_pred = lr.predict(df)\n",
"NN_pred = NN.predict(df)\n",
"print('linear regression',new_pred)\n",
"print('Neural Network',NN_pred)\n",
"print('Actual Travel Time :- 58')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Testing With Current Data"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Time</th>\n",
" <th>Day</th>\n",
" <th>Special</th>\n",
" <th>Congestion</th>\n",
" <th>Drving Speed</th>\n",
" <th>Stops</th>\n",
" <th>Weather</th>\n",
" <th>Distance</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>17</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5</td>\n",
" <td>40</td>\n",
" <td>20</td>\n",
" <td>24</td>\n",
" <td>14.7</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Time Day Special Congestion Drving Speed Stops Weather Distance\n",
"0 17 1 0 5 40 20 24 14.7"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = {'Time':17,\n",
" 'Day':1,\n",
" 'Special':0,\n",
" 'Congestion':5,\n",
" 'Drving Speed':40,\n",
" 'Stops':20,\n",
" 'Weather':24,\n",
" 'Distance':14.7\n",
" }\n",
"ddf = pd.DataFrame(data,index=[0])\n",
"ddf"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Travel Time Prediction :- 56 Min\n"
]
}
],
"source": [
"resultsNN = NN.predict(ddf)\n",
"resultsNN\n",
"print('Travel Time Prediction :-',*resultsNN,'Min')"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
"def GetPrediction(time,date,special,congestion,dspeed,stops,weather,distance):\n",
" data = {'Time':time,\n",
" 'Day':date,\n",
" 'Special':special,\n",
" 'Congestion':congestion,\n",
" 'Drving Speed':dspeed,\n",
" 'Stops':stops,\n",
" 'Weather':weather,\n",
" 'Distance':distance\n",
" }\n",
" ddf = pd.DataFrame(data,index=[0])\n",
" resultsNN = NN.predict(ddf)\n",
" resultsNN\n",
" print('Travel Time Prediction :-',*resultsNN,'Min')"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Travel Time Prediction :- 55 Min\n"
]
}
],
"source": [
"def GetDateCode(date):\n",
" if('Sunday' == date ):\n",
" return 0\n",
" elif('Monday' == date):\n",
" return 1\n",
" elif('Tuesday' == date):\n",
" return 2\n",
" elif('Wednesday' == date):\n",
" return 3\n",
" elif('Thursday' == date):\n",
" return 4\n",
" elif('Friday' == date):\n",
" return 5\n",
" elif('Saturday' == date):\n",
" return 6\n",
" else:\n",
" return 9\n",
" \n",
"\n",
" \n",
"time= 6 #this time come from semins data/member of route planning\n",
"day ='Friday' #date come from UI \n",
"date = GetDateCode(day)\n",
"special = 0 # Special Day or Not 1/0\n",
"Congestion= 8 # This is depend on the depature time---- heavy traffic =9 / No Traffic = 0 \n",
"drivingspeedAVG = 40 #this is come from GPS data\n",
"stops =14 #total Bus stops/holts between the travel --- data come from the Seminas data/member of route planning \n",
"weather =23 #Get weather in travel area\n",
"\n",
"\n",
"GetPrediction(time,date,special,Congestion,drivingspeedAVG,14,24,14.7)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.10.7 64-bit",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.7"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "26de051ba29f2982a8de78e945f0abaf191376122a1563185a90213a26c5da77"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
# %%
import pandas as pd
# %%
data = pd.read_csv('BusTravelData.csv')
# %%
data['Day'].unique()
# %%
data['Day'].map({'Sunday':0,'Monday':1,'Tuesday':2})
# %%
data['Day'] = data['Day'].map({'Sunday':0,'Monday':1,'Tuesday':2})
# %%
data.head()
# %%
data['Special'] = data['Special'].map({'No':0,'Yes':1})
# %%
data.tail()
# %%
data['Weather'].unique()
# %%
data.columns
# %%
X = data.drop(['Date','Travel Time'],axis=1)
# %%
y = data['Travel Time']
# %% [markdown]
# Train/test split
#
# 1. split data into two parts
#
# training data set
# testing data set
#
# 2. Train the models on training set
#
# 3. Test the models on testing data set
# %%
from sklearn.model_selection import train_test_split
# %%
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)
# %%
y_train
# %%
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.neural_network import MLPClassifier
# %%
lr = LinearRegression()
NN = MLPClassifier()
lr.fit(X_train,y_train)
NN.fit(X_train,y_train)
# %%
y_pred1 = lr.predict(X_test)
# %%
df1 = pd.DataFrame({'Actual':y_test, 'Lr Results':y_pred1})
# %%
df1
# %%
y_pred2 = NN.predict(X_test)
df2 = pd.DataFrame({'Actual':y_test, 'NN Results':y_pred2, 'LR Results':y_pred1})
df2
# %%
import matplotlib.pyplot as plt
# %%
plt.subplot(221)
plt.plot(df1['Actual'].iloc[0:11],label='Actual')
plt.plot(df1['Lr Results'].iloc[0:11],label='Lr Results')
plt.legend()
# %% [markdown]
# Time Day Rush Special Congestion Drving Speed Stops Weather Distance Travel Time
# %%
plt.subplot(221)
plt.plot(df1['Actual'].iloc[0:11],label='Actual')
plt.plot(df2['NN Results'].iloc[0:11],label='NN Results')
plt.legend()
# %% [markdown]
# Prediction with Current parameters (Predict Time with trained Model)
# %%
data = {'Time':6,
'Day':1,
'Special':0,
'Congestion':8,
'Drving Speed':40,
'Stops':14,
'Weather':23,
'Distance':14.7
}
df = pd.DataFrame(data,index=[0])
df
# %%
new_pred = lr.predict(df)
NN_pred = NN.predict(df)
# %%
data = {'Time':17,
'Day':1,
'Special':0,
'Congestion':5,
'Drving Speed':40,
'Stops':20,
'Weather':24,
'Distance':14.7
}
ddf = pd.DataFrame(data,index=[0])
ddf
# %%
resultsNN = NN.predict(ddf)
resultsNN
# %%
def GetPrediction(time,date,special,congestion,dspeed,stops,weather,distance):
data = {'Time':time,
'Day':date,
'Special':special,
'Congestion':congestion,
'Drving Speed':dspeed,
'Stops':stops,
'Weather':weather,
'Distance':distance
}
ddf = pd.DataFrame(data,index=[0])
resultsNN = NN.predict(ddf)
resultsNN
print('Travel Time Prediction :-',*resultsNN,'Min')
# %%
def GetDateCode(date):
if('Sunday' == date ):
return 0
elif('Monday' == date):
return 1
elif('Tuesday' == date):
return 2
elif('Wednesday' == date):
return 3
elif('Thursday' == date):
return 4
elif('Friday' == date):
return 5
elif('Saturday' == date):
return 6
else:
return 9
import testingWeather
city = "malabe"
city = city+" weather"
time= 6 #this time come from semins data/member of route planning
day ='Friday' #date come from UI
date = GetDateCode(day)
special = 0 # Special Day or Not 1/0
Congestion= 8 # This is depend on the depature time---- heavy traffic =9 / No Traffic = 0
drivingspeedAVG = 40 #this is come from GPS data
stops =14 #total Bus stops/holts between the travel --- data come from the Seminas data/member of route planning
weather =testingWeather.weather(city) #Get weather in travel area
Distance =14.7 #Distance data come from seminas ----- data come from the Seminas data/member of route planning
GetPrediction(time,date,special,Congestion,drivingspeedAVG,stops,weather,Distance)
...@@ -11,7 +11,6 @@ import androidx.navigation.fragment.NavHostFragment; ...@@ -11,7 +11,6 @@ import androidx.navigation.fragment.NavHostFragment;
import com.app.travelle.databinding.FragmentFirstBinding; import com.app.travelle.databinding.FragmentFirstBinding;
public class FirstFragment extends Fragment { public class FirstFragment extends Fragment {
private FragmentFirstBinding binding; private FragmentFirstBinding binding;
@Override @Override
......
...@@ -32,7 +32,6 @@ public class HomeMap extends FragmentActivity implements OnMapReadyCallback { ...@@ -32,7 +32,6 @@ public class HomeMap extends FragmentActivity implements OnMapReadyCallback {
binding = ActivityHomeMapBinding.inflate(getLayoutInflater()); binding = ActivityHomeMapBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
// Obtain the SupportMapFragment and get notified when the map is ready to be used. // Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map); .findFragmentById(R.id.map);
......
...@@ -44,7 +44,6 @@ public class InitialMap extends AppCompatActivity { ...@@ -44,7 +44,6 @@ public class InitialMap extends AppCompatActivity {
getSupportActionBar().hide(); getSupportActionBar().hide();
setContentView(R.layout.activity_initial_map); setContentView(R.layout.activity_initial_map);
//Assign variable //Assign variable
supportMapFragment = (SupportMapFragment) getSupportFragmentManager() supportMapFragment = (SupportMapFragment) getSupportFragmentManager()
......
...@@ -45,4 +45,5 @@ public class Login extends AppCompatActivity { ...@@ -45,4 +45,5 @@ public class Login extends AppCompatActivity {
startActivity(intent); startActivity(intent);
} }
} }
\ No newline at end of file
...@@ -32,6 +32,7 @@ public class MainActivity extends AppCompatActivity { ...@@ -32,6 +32,7 @@ public class MainActivity extends AppCompatActivity {
} }
}); });
} }
public void openLogin(){ public void openLogin(){
Intent intent = new Intent(this, Login.class); Intent intent = new Intent(this, Login.class);
startActivity(intent); startActivity(intent);
......
...@@ -14,6 +14,7 @@ public class SecondFragment extends Fragment { ...@@ -14,6 +14,7 @@ public class SecondFragment extends Fragment {
private FragmentSecondBinding binding; private FragmentSecondBinding binding;
@Override @Override
public View onCreateView( public View onCreateView(
LayoutInflater inflater, ViewGroup container, LayoutInflater inflater, ViewGroup container,
......
...@@ -14,5 +14,6 @@ public class Signup extends AppCompatActivity { ...@@ -14,5 +14,6 @@ public class Signup extends AppCompatActivity {
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getSupportActionBar().hide(); getSupportActionBar().hide();
setContentView(R.layout.activity_signup); setContentView(R.layout.activity_signup);
} }
} }
\ No newline at end of file
...@@ -10,5 +10,6 @@ public class Welcome extends AppCompatActivity { ...@@ -10,5 +10,6 @@ public class Welcome extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome); setContentView(R.layout.activity_welcome);
} }
} }
\ No newline at end of file
#include <WiFi.h>
#include <FirebaseESP32.h>
#include <TinyGPS++.h>
#define FIREBASE_HOST "gps-b123c-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "gEjXkGOWaMEzkZKpKIYqwFH7dQMetih25gsmligT"
#define WIFI_SSID "LAZI 5G"
#define WIFI_PASSWORD "fmrp1530"
FirebaseData firebaseData;
#define RXD2 5
#define TXD2 21
HardwareSerial neogps(1);
String ESP32_API_KEY = "Ad5F10jkBM0";
TinyGPSPlus gps;
void setup(){
Initialization();
WiFiConnection();
neogps.begin(9600, SERIAL_8N1, RXD2, TXD2);
}
float counter2 = 0.5;
void Initialization(){
Serial.begin(115200);
}
void WiFiConnection(){
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
}
void loop(){
boolean newData = false;
for (unsigned long start = millis(); millis() - start < 2000;){
while(neogps.available()){
if(gps.encode(neogps.read())){
if(gps.location.isValid() == 1){
newData = true;
break;
}
}
}
}
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
//If newData is true
if(true){
newData = false;
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
String latitude, longitude;
//float altitude;
//unsigned long date, time, speed, satellites;
latitude = String(gps.location.lat(), 6); // Latitude in degrees (double)
longitude = String(gps.location.lng(), 6); // Longitude in degrees (double)
//altitude = gps.altitude.meters(); // Altitude in meters (double)
//date = gps.date.value(); // Raw date in DDMMYY format (u32)
//time = gps.time.value(); // Raw time in HHMMSSCC format (u32)
//speed = gps.speed.kmph();
//Serial.print("Latitude= ");
//Serial.print(latitude);
//Serial.print(" Longitude= ");
//Serial.println(longitude);
String gps_data;
gps_data = "api_key="+ESP32_API_KEY;
gps_data += "&lat="+latitude;
gps_data += "&lng="+longitude;
Serial.print("gps_data: ");
Serial.println(gps_data);
String x = gps_data;
if(Firebase.setString(firebaseData, "location", x)){
}
if(Firebase.getString(firebaseData, "location")){
if(firebaseData.dataType() == "string"){
Serial.print("data = ");
Serial.println(firebaseData.stringData());
}
}
}
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Travelle Dashboard</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
</head>
<body>
<div class="container" style="margin-top: 50px;">
<h4 class="text-center">Travelle Dashboard</h4><br>
<h5>Add Option</h5>
<div class="card card-default">
<div class="card-body">
<form id="addUser" class="form-inline" method="POST" action="">
<div class="form-group mb-2">
<label for="name" class="sr-only">Name</label>
<input id="name" type="text" class="form-control" name="name" placeholder="Name"
required autofocus>
</div>
<div class="form-group mx-sm-3 mb-2">
<label for="email" class="sr-only">Cordinates</label>
<input id="email" type="email" class="form-control" name="email" placeholder="Email"
required autofocus>
</div>
<button id="submitUser" type="button" class="btn btn-primary mb-2">Submit</button>
</form>
</div>
</div>
<br>
<h5>Users</h5>
<table class="table table-bordered">
<tr>
<th>Name</th>
<th>Email</th>
<th width="180" class="text-center">Action</th>
</tr>
<tbody id="tbody">
</tbody>
</table>
</div>
<!-- Update Model -->
<form action="" method="POST" class="users-update-record-model form-horizontal">
<div id="update-modal" data-backdrop="static" data-keyboard="false" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="custom-width-modalLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" style="width:55%;">
<div class="modal-content" style="overflow: hidden;">
<div class="modal-header">
<h4 class="modal-title" id="custom-width-modalLabel">Update</h4>
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×
</button>
</div>
<div class="modal-body" id="updateBody">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light"
data-dismiss="modal">Close
</button>
<button type="button" class="btn btn-success updateUser">Update
</button>
</div>
</div>
</div>
</div>
</form>
<!-- Delete Model -->
<form action="" method="POST" class="users-remove-record-model">
<div id="remove-modal" data-backdrop="static" data-keyboard="false" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="custom-width-modalLabel"
aria-hidden="true" style="display: none;">
<div class="modal-dialog modal-dialog-centered" style="width:55%;">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="custom-width-modalLabel">Delete</h4>
<button type="button" class="close remove-data-from-delete-form" data-dismiss="modal" aria-hidden="true">×
</button>
</div>
<div class="modal-body">
<p>Do you want to delete this record?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default waves-effect remove-data-from-delete-form"
data-dismiss="modal">Close
</button>
<button type="button" class="btn btn-danger waves-effect waves-light deleteRecord">Delete
</button>
</div>
</div>
</div>
</div>
</form>
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.14.6/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.14.6/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.6/firebase-database.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyDqcBd6B-l2_rPVslln0lMbw7zPw-8JDd0",
authDomain: "travelle-99619.firebaseapp.com",
projectId: "travelle-99619",
storageBucket: "travelle-99619.appspot.com",
messagingSenderId: "636540305419",
appId: "1:636540305419:web:f0d4c40fe85f03c15b470e",
measurementId: "G-8G2072NEWL"
};
firebase.initializeApp(config);
firebase.analytics();
var database = firebase.database();
var lastIndex = 0;
// Get Data
firebase.database().ref('Users/').on('value', function (snapshot) {
var value = snapshot.val();
var htmls = [];
$.each(value, function (index, value) {
if (value) {
htmls.push('<tr>\
<td>' + value.name + '</td>\
<td>' + value.email + '</td>\
<td><button data-toggle="modal" data-target="#update-modal" class="btn btn-info updateData" data-id="' + index + '">Update</button>\
<button data-toggle="modal" data-target="#remove-modal" class="btn btn-danger removeData" data-id="' + index + '">Delete</button></td>\
</tr>');
}
lastIndex = index;
});
$('#tbody').html(htmls);
$("#submitUser").removeClass('desabled');
});
// Add Data
$('#submitUser').on('click', function () {
var values = $("#addUser").serializeArray();
var name = values[0].value;
var email = values[1].value;
var userID = lastIndex + 1;
console.log(values);
firebase.database().ref('Users/' + userID).set({
name: name,
email: email,
});
// Reassign lastID value
lastIndex = userID;
$("#addUser input").val("");
});
// Update Data
var updateID = 0;
$('body').on('click', '.updateData', function () {
updateID = $(this).attr('data-id');
firebase.database().ref('Users/' + updateID).on('value', function (snapshot) {
var values = snapshot.val();
var updateData = '<div class="form-group">\
<label for="first_name" class="col-md-12 col-form-label">Name</label>\
<div class="col-md-12">\
<input id="first_name" type="text" class="form-control" name="name" value="' + values.name + '" required autofocus>\
</div>\
</div>\
<div class="form-group">\
<label for="last_name" class="col-md-12 col-form-label">Email</label>\
<div class="col-md-12">\
<input id="last_name" type="text" class="form-control" name="email" value="' + values.email + '" required autofocus>\
</div>\
</div>';
$('#updateBody').html(updateData);
});
});
$('.updateUser').on('click', function () {
var values = $(".users-update-record-model").serializeArray();
var postData = {
name: values[0].value,
email: values[1].value,
};
var updates = {};
updates['/Users/' + updateID] = postData;
firebase.database().ref().update(updates);
$("#update-modal").modal('hide');
});
// Remove Data
$("body").on('click', '.removeData', function () {
var id = $(this).attr('data-id');
$('body').find('.users-remove-record-model').append('<input name="id" type="hidden" value="' + id + '">');
});
$('.deleteRecord').on('click', function () {
var values = $(".users-remove-record-model").serializeArray();
var id = values[0].value;
firebase.database().ref('Users/' + id).remove();
$('body').find('.users-remove-record-model').find("input").remove();
$("#remove-modal").modal('hide');
});
$('.remove-data-from-delete-form').click(function () {
$('body').find('.users-remove-record-model').find("input").remove();
});
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>
from helpers import load_map_test, load_map_bus, load_map_train,route_177
import math
val = 0
class PathPlanner():
def __init__(self, M, start=None, goal=None, type=None):
self.map = M
self.start= start
self.goal = goal
self.type = type
self.dis = 0
self.closedSet = self.create_closedSet() if goal != None and start != None else None
self.openSet = self.create_openSet() if goal != None and start != None else None
self.cameFrom = self.create_cameFrom() if goal != None and start != None else None
self.gScore = self.create_gScore() if goal != None and start != None else None
self.fScore = self.create_fScore() if goal != None and start != None else None
self.path = self.run_search() if self.map and self.start != None and self.goal != None else None
def reconstruct_path(self, current):
total_path = [current]
while current in self.cameFrom.keys():
current = self.cameFrom[current]
total_path.append(current)
return total_path
def _reset(self):
self.closedSet = None
self.openSet = None
self.cameFrom = None
self.gScore = None
self.fScore = None
self.path = self.run_search() if self.map and self.start and self.goal else None
def run_search(self):
""" """
if self.map == None:
raise(ValueError, "Must create map before running search")
if self.goal == None:
raise(ValueError, "Must create goal node before running search")
if self.start == None:
raise(ValueError, "Must create start node before running search")
self.closedSet = self.closedSet if self.closedSet != None else self.create_closedSet()
self.openSet = self.openSet if self.openSet != None else self.create_openSet()
self.cameFrom = self.cameFrom if self.cameFrom != None else self.create_cameFrom()
self.gScore = self.gScore if self.gScore != None else self.create_gScore()
self.fScore = self.fScore if self.fScore != None else self.create_fScore()
while not self.is_open_empty():
current = self.get_current_node()
if current == self.goal:
self.path = [x for x in reversed(self.reconstruct_path(current))]
return self.path
else:
self.openSet.remove(current)
self.closedSet.add(current)
for neighbor in self.get_neighbors(current):
if neighbor in self.closedSet:
continue # Ignore the neighbor which is already evaluated.
if not neighbor in self.openSet: # Discover a new node
self.openSet.add(neighbor)
# The distance from start to a neighbor
if self.getTempGScore(current, neighbor) >= self.get_gScore(neighbor):
continue
# This path is the best until now. Record it!
global val #
val = val + self.dis
self.record_best_path_to(current, neighbor)
print("No Path Found")
self.path = None
return False
def create_closedSet(self):
return set()
def create_openSet(self):
openSet = set()
openSet.add(self.start)
return openSet
def create_cameFrom(self):
cameFrom = {}
return cameFrom
def create_gScore(self):
gScore = {}
for node in self.map.intersections.keys():
if node == self.start:
gScore[node] = 0
else: gScore[node] = float('inf')
return gScore
def create_fScore(self):
if self.start != None:
fScore = {}
for node in self.map.intersections.keys():
if node == self.start:
fScore[node] = self.heuristic_cost_estimate(self.start)
else: fScore[node] = float('inf')
return fScore
raise(ValueError, "Must create start node before creating fScore.")
def set_map(self, M):
"set map attribute "
self._reset(self)
self.start = None
self.goal = None
self.map = M
def set_start(self, start):
" set start attribute "
self._reset(self)
self.start = start
self.goal = None
def set_goal(self, goal):
"set goal attribute "
self._reset(self)
self.goal = goal
#-------------------------------- get information --------------------------------#
def is_open_empty(self):
"returns True if the open set is empty"
return not bool(self.openSet)
def get_current_node(self):
" Returns the node in the open set with the lowest value of f(node)"
current = None
minim = float('inf')
for node in self.openSet:
if self.fScore[node] < minim:
minim = self.fScore[node]
current = node
return current
def get_neighbors(self, node):
"""Returns the neighbors of a node"""
return set(self.map.roads[node])
def get_traveled_distance(self):
#traveled_distance
return self.dis
#-------------------------------- Calculations --------------------------------#
def get_gScore(self, node):
return self.gScore[node]
def getTempGScore(self, current, neighbor):
# distance from the current node to it's neighbors
g_score_current = self.get_gScore(current)
dist_current_neighbor = self.distance(current,neighbor)
return g_score_current+dist_current_neighbor
def heuristic_cost_estimate(self, node):
if self.goal != None:
heuristic_estimate = self.distance(node,self.goal)
return heuristic_estimate
raise(ValueError, "Must create goal node before calculating huristic ")
def calculate_fscore(self, node):
# F = G + H
f_score = self.get_gScore(node) + self.heuristic_cost_estimate(node)
return f_score
# best path
def record_best_path_to(self, current, neighbor):
self.cameFrom[neighbor] = current
self.gScore[neighbor] = self.getTempGScore(current,neighbor)
self.fScore[neighbor] = self.gScore[neighbor] + self.heuristic_cost_estimate(neighbor)
def distance(self, node_1, node_2):
from math import radians, cos, sin, asin, sqrt
#The math module contains a function named
#radians which converts from degrees to radians.
lon1 = radians(self.map.intersections [node_1][0])
lon2 = radians(self.map.intersections [node_2][0])
lat1 = radians(self.map.intersections [node_1][1])
lat2 = radians(self.map.intersections [node_2][1])
# Haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * asin(sqrt(a))
# Radius of earth in kilometers. Use 3956 for miles
r = 6371
# calculate the result
dist = (c * r)
#print (dist)
self.dis = dist
return dist
# Get route
def main( a, node1, node2):
if a == 3:
map = load_map_train()
elif a == 2:
map = load_map_bus()
else:
map = load_map_test()
planner = PathPlanner(map,node1,node2)
print(map.roads)
path = planner.path
print('distance =' ,val)
if path == [5, 16, 37, 12, 34]:
print("code works for test path!!!")
print(path)
else:
print("Genarated path")
print(path)
# for x in path:
# if routeNo
# print (x)
#for each in path:
main( 1, 2, 14)
\ No newline at end of file
import networkx as nx
import pickle
from chart_studio import plotly as py
import random
from plotly.graph_objs import *
from plotly.offline import init_notebook_mode, plot, iplot
#init_notebook_mode(connected=True)
route_177 = {
1: 34,
2: 42,
3: 54,
4: 67,
5: 80,
6: 92,
7: 105,
8: 109,
9: 117,
10: 126,
11: 134,
12: 140,
13: 149,
14: 157,
15: 163,
}
map_test = {
0: {'pos': (6.911034627182109, 79.84918916006576), 'connections': [1], 'name' : 'Kollupitiya','type': 0,'routeNo': 177, 'hValue': 1},
1: {'pos': (6.911751932322411, 79.86194701315071), 'connections': [0,2], 'name' : 'Viharamahadevi Park', 'type': 0, 'routeNo': 177, 'hValue': 1},
2: {'pos': (6.911385550864001, 79.87682791026592), 'connections': [1,3], 'name' : 'House Of Fashion', 'type': 0, 'routeNo': 177, 'hValue': 1},
3: {'pos': (6.911031363415147, 79.88498429384545), 'connections': [2,4], 'name' : 'Castle Street', 'type': 0, 'routeNo': 177, 'hValue': 1},
4: {'pos': (6.908462881966912, 79.89338919261249), 'connections': [3,5], 'name' : 'Rajagiriya', 'type': 0, 'routeNo': 177, 'hValue': 1},
5: {'pos': (6.906663916178293, 79.90205413217801), 'connections': [4,6], 'name' : 'Hsbc Rajagiriya', 'type': 0, 'routeNo': 177, 'hValue': 1},
6: {'pos': (6.90333333857459, 79.90747047529919), 'connections': [5,7], 'name' : 'Ethulkotte New', 'type': 0, 'routeNo': 177, 'hValue': 1},
7: {'pos': (6.903185701293392, 79.91168232658337), 'connections': [6,8], 'name' : 'Parliament Junction', 'type': 0, 'routeNo': 177, 'hValue': 1},
8: {'pos': (6.902102452411621, 79.91741047710077), 'connections': [7,9], 'name' : 'Battaramulla Junction', 'type': 0, 'routeNo': 177, 'hValue': 1},
9: {'pos': (6.90431022366131, 79.92400480782847), 'connections': [8,10], 'name' : 'Ganahena', 'type': 0, 'routeNo': 177, 'hValue': 1},
10: {'pos': (6.906173952520986, 79.92862087153598), 'connections': [9,11], 'name' : 'Koswatta', 'type': 0, 'routeNo': 177, 'hValue': 1},
11: {'pos': (6.9084657304543455, 79.9383708894408), 'connections': [10,12], 'name' : 'Kotte-Bope', 'type': 0, 'routeNo': 177, 'hValue': 1},
12: {'pos': (6.9085023402918155, 79.94425286198016), 'connections': [11,13], 'name' : 'Thalahena Junction', 'type': 0, 'routeNo': 177, 'hValue': 1},
13: {'pos': (6.903962700873259, 79.95430199947661), 'connections': [12,14], 'name' : 'Malabe', 'type': 0, 'routeNo': 177, 'hValue': 1},
14: {'pos': (6.933539686667202, 79.85005389798111), 'connections': [15], 'name' : 'Fort', 'type': 1, 'routeNo': 8717, 'hValue': 1},
15: {'pos': (6.923619774894732, 79.84965509086771), 'connections': [14,16], 'name' : 'Kompannavidiya', 'type': 1, 'routeNo': 8717, 'hValue': 1},
16: {'pos': (6.911282166657041, 79.84821747831087), 'connections': [15,1,17], 'name' : 'Kollupitiya', 'type': 1, 'routeNo': 8717, 'hValue': 1},
17: {'pos': (6.893710110662125, 79.85300590028642), 'connections': [16,18], 'name' : 'Bambalapitiya', 'type': 1, 'routeNo': 8717, 'hValue': 1},
18: {'pos': (6.875030063532378, 79.85744793142631), 'connections': [17,19], 'name' : 'Wellawatte', 'type': 1, 'routeNo': 8717, 'hValue': 1},
19: {'pos': (6.850915755796403, 79.8620969312958), 'connections': [18], 'name' : 'Dehiwala ', 'type': 1, 'routeNo': 8717, 'hValue': 1},
}
class Map:
def __init__(self, G):
self._graph = G
self.intersections = nx.get_node_attributes(G, "pos")
self.routeNo = nx.get_node_attributes(G, "routeNo")
self.type = nx.get_node_attributes(G, "type")
self.roads = [list(G[node]) for node in G.nodes()]
def save(self, filename):
with open(filename, 'wb') as f:
pickle.dump(self._graph, f)
def load_map_graph(map_dict):
G = nx.Graph()
for node in map_dict.keys():
G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
for node in map_dict.keys():
for con_node in map_dict[node]['connections']:
G.add_edge(node, con_node)
return G
def load_map_b(map_dict):
# G = nx.Graph()
# for node in map_dict.keys():
# #nodeValue =
# if map_dict[node]['type'] != 1:
# continue
# else:
# G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
G = nx.Graph()
for node in map_dict.keys():
G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
# for node in map_dict.keys():
# for con_node in map_dict[node]['connections']:
# if map_dict[con_node]['type'] != 1:
# continue
# else:
# G.add_edge(node, con_node)
for node in map_dict.keys():
for con_node in map_dict[node]['connections']:
if map_dict[node]['type'] != 1:
continue
elif map_dict[con_node]['type'] != 1:
continue
else:
G.add_edge(node, con_node)
return G
#map for train
def load_map_t(map_dict):
G = nx.Graph()
for node in map_dict.keys():
G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
for node in map_dict.keys():
for con_node in map_dict[node]['connections']:
if map_dict[node]['type'] == 1:
continue
elif map_dict[con_node]['type'] == 1:
continue
else:
G.add_edge(node, con_node)
return G
def load_map_test():
G = load_map_graph(map_test)
return Map(G)
def load_map_bus():
G = load_map_b(map_test)
return Map(G)
def load_map_train():
G = load_map_t(map_test)
return Map(G)
from helpers import load_map_40
MAP_40_ANSWERS = [
(5, 34, [5, 16, 37, 12, 34]),
(5, 5, [5]),
(8, 24, [8, 14, 16, 37, 12, 17, 10, 24])
]
def test(shortest_path_function):
map_40 = load_map_40()
correct = 0
for start, goal, answer_path in MAP_40_ANSWERS:
path = shortest_path_function(map_40, start, goal).path
if path == answer_path:
correct += 1
print("For start:", start,
"Goal: ", goal,
"Your path:", path,
"Correct: ", answer_path)
else:
print("Error Testing faild !!!" )
if correct == len(MAP_40_ANSWERS):
print("All tests pass ")
else:
print("Only passed", correct, "/", len(MAP_40_ANSWERS), "test cases")
\ No newline at end of file
from bs4 import BeautifulSoup
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
def weather(city):
city = city.replace(" ", "+")
res = requests.get(
f'https://www.google.com/search?q={city}&oq={city}&aqs=chrome.0.35i39l2j0l4j46j69i60.6128j1j7&sourceid=chrome&ie=UTF-8', headers=headers)
soup = BeautifulSoup(res.text, 'html.parser')
location = soup.select('#wob_loc')[0].getText().strip()
time = soup.select('#wob_dts')[0].getText().strip()
info = soup.select('#wob_dc')[0].getText().strip()
weather = soup.select('#wob_tm')[0].getText().strip()
return weather
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment