diff --git a/293/BlueBar1.jpg b/293/BlueBar1.jpg new file mode 100644 index 0000000000..1a378f716a Binary files /dev/null and b/293/BlueBar1.jpg differ diff --git a/293/Chinook_Sqlite.sqlite b/293/Chinook_Sqlite.sqlite new file mode 100644 index 0000000000..b559c7394a Binary files /dev/null and b/293/Chinook_Sqlite.sqlite differ diff --git a/293/NR b/293/NR new file mode 100644 index 0000000000..4438e30535 --- /dev/null +++ b/293/NR @@ -0,0 +1 @@ +293 diff --git a/293/REPO b/293/REPO new file mode 100644 index 0000000000..f5aa6603d1 --- /dev/null +++ b/293/REPO @@ -0,0 +1 @@ +ivanuxowo/PyZombis diff --git a/293/_images/TWP05_015.png b/293/_images/TWP05_015.png new file mode 100644 index 0000000000..121a317761 Binary files /dev/null and b/293/_images/TWP05_015.png differ diff --git a/293/_images/TWP05_035.jpeg b/293/_images/TWP05_035.jpeg new file mode 100644 index 0000000000..2cdd88a4ec Binary files /dev/null and b/293/_images/TWP05_035.jpeg differ diff --git a/293/_images/TWP05_041.jpeg b/293/_images/TWP05_041.jpeg new file mode 100644 index 0000000000..e6f0ad6309 Binary files /dev/null and b/293/_images/TWP05_041.jpeg differ diff --git a/293/_images/TWP10_001.jpeg b/293/_images/TWP10_001.jpeg new file mode 100644 index 0000000000..d54fd2f4c8 Binary files /dev/null and b/293/_images/TWP10_001.jpeg differ diff --git a/293/_images/TWP10_002.jpg b/293/_images/TWP10_002.jpg new file mode 100644 index 0000000000..61d24a2d87 Binary files /dev/null and b/293/_images/TWP10_002.jpg differ diff --git a/293/_images/TWP10_004.png b/293/_images/TWP10_004.png new file mode 100644 index 0000000000..dcdbbf0f60 Binary files /dev/null and b/293/_images/TWP10_004.png differ diff --git a/293/_images/TWP10_009.jpg b/293/_images/TWP10_009.jpg new file mode 100644 index 0000000000..b9fbf1628f Binary files /dev/null and b/293/_images/TWP10_009.jpg differ diff --git a/293/_images/TWP10_011.jpg b/293/_images/TWP10_011.jpg new file mode 100644 index 0000000000..f3ea12eb2f Binary files /dev/null and b/293/_images/TWP10_011.jpg differ diff --git a/293/_images/TWP15_001.jpg b/293/_images/TWP15_001.jpg new file mode 100644 index 0000000000..4e91e1edb3 Binary files /dev/null and b/293/_images/TWP15_001.jpg differ diff --git a/293/_images/TWP15_002.jpeg b/293/_images/TWP15_002.jpeg new file mode 100644 index 0000000000..f9442d9051 Binary files /dev/null and b/293/_images/TWP15_002.jpeg differ diff --git a/293/_images/TWP15_007.jpeg b/293/_images/TWP15_007.jpeg new file mode 100644 index 0000000000..6703e22051 Binary files /dev/null and b/293/_images/TWP15_007.jpeg differ diff --git a/293/_images/TWP15_007.png b/293/_images/TWP15_007.png new file mode 100644 index 0000000000..8ee3cac657 Binary files /dev/null and b/293/_images/TWP15_007.png differ diff --git a/293/_images/TWP17_004.jpg b/293/_images/TWP17_004.jpg new file mode 100644 index 0000000000..6ef00f2f8a Binary files /dev/null and b/293/_images/TWP17_004.jpg differ diff --git a/293/_images/TWP17_005.png b/293/_images/TWP17_005.png new file mode 100644 index 0000000000..be5e22ef81 Binary files /dev/null and b/293/_images/TWP17_005.png differ diff --git a/293/_images/TWP17_006.png b/293/_images/TWP17_006.png new file mode 100644 index 0000000000..0f9cc17bc5 Binary files /dev/null and b/293/_images/TWP17_006.png differ diff --git a/293/_images/TWP17_007.png b/293/_images/TWP17_007.png new file mode 100644 index 0000000000..bbed8bda36 Binary files /dev/null and b/293/_images/TWP17_007.png differ diff --git a/293/_images/TWP18_015.jpeg b/293/_images/TWP18_015.jpeg new file mode 100644 index 0000000000..c42cea26e8 Binary files /dev/null and b/293/_images/TWP18_015.jpeg differ diff --git a/293/_images/TWP18_016.png b/293/_images/TWP18_016.png new file mode 100644 index 0000000000..6c9847a3fd Binary files /dev/null and b/293/_images/TWP18_016.png differ diff --git a/293/_images/TWP18_017.jpeg b/293/_images/TWP18_017.jpeg new file mode 100644 index 0000000000..5bd908f36f Binary files /dev/null and b/293/_images/TWP18_017.jpeg differ diff --git a/293/_images/TWP18_018.png b/293/_images/TWP18_018.png new file mode 100644 index 0000000000..86033f7faa Binary files /dev/null and b/293/_images/TWP18_018.png differ diff --git a/293/_images/TWP30_001.jpeg b/293/_images/TWP30_001.jpeg new file mode 100644 index 0000000000..c85eceb18d Binary files /dev/null and b/293/_images/TWP30_001.jpeg differ diff --git a/293/_images/TWP30_002.jpeg b/293/_images/TWP30_002.jpeg new file mode 100644 index 0000000000..9317286ded Binary files /dev/null and b/293/_images/TWP30_002.jpeg differ diff --git a/293/_images/TWP30_004.png b/293/_images/TWP30_004.png new file mode 100644 index 0000000000..c84d9a7057 Binary files /dev/null and b/293/_images/TWP30_004.png differ diff --git a/293/_images/TWP30_005.png b/293/_images/TWP30_005.png new file mode 100644 index 0000000000..2f576ab80f Binary files /dev/null and b/293/_images/TWP30_005.png differ diff --git a/293/_images/TWP30_006.jpg b/293/_images/TWP30_006.jpg new file mode 100644 index 0000000000..eb9a21ba5c Binary files /dev/null and b/293/_images/TWP30_006.jpg differ diff --git a/293/_images/TWP30_009.jpg b/293/_images/TWP30_009.jpg new file mode 100644 index 0000000000..64b6bef78b Binary files /dev/null and b/293/_images/TWP30_009.jpg differ diff --git a/293/_images/TWP30_0092.jpg b/293/_images/TWP30_0092.jpg new file mode 100644 index 0000000000..e30d837ef5 Binary files /dev/null and b/293/_images/TWP30_0092.jpg differ diff --git a/293/_images/TWP30_012.jpg b/293/_images/TWP30_012.jpg new file mode 100644 index 0000000000..51c39b228c Binary files /dev/null and b/293/_images/TWP30_012.jpg differ diff --git a/293/_images/TWP33_001.jpg b/293/_images/TWP33_001.jpg new file mode 100644 index 0000000000..4113e68687 Binary files /dev/null and b/293/_images/TWP33_001.jpg differ diff --git a/293/_images/TWP33_004.jpg b/293/_images/TWP33_004.jpg new file mode 100644 index 0000000000..354a100675 Binary files /dev/null and b/293/_images/TWP33_004.jpg differ diff --git a/293/_images/TWP33_005.png b/293/_images/TWP33_005.png new file mode 100644 index 0000000000..3c6d1c160a Binary files /dev/null and b/293/_images/TWP33_005.png differ diff --git a/293/_images/TWP33_006.png b/293/_images/TWP33_006.png new file mode 100644 index 0000000000..39d90ff9e6 Binary files /dev/null and b/293/_images/TWP33_006.png differ diff --git a/293/_images/TWP33_007.jpg b/293/_images/TWP33_007.jpg new file mode 100644 index 0000000000..43a47b8f7f Binary files /dev/null and b/293/_images/TWP33_007.jpg differ diff --git a/293/_images/TWP33_008.jpg b/293/_images/TWP33_008.jpg new file mode 100644 index 0000000000..c7e843fb1f Binary files /dev/null and b/293/_images/TWP33_008.jpg differ diff --git a/293/_images/TWP33_009.jpg b/293/_images/TWP33_009.jpg new file mode 100644 index 0000000000..3bef2f1dcd Binary files /dev/null and b/293/_images/TWP33_009.jpg differ diff --git a/293/_images/TWP33_012.jpg b/293/_images/TWP33_012.jpg new file mode 100644 index 0000000000..eac1c42aae Binary files /dev/null and b/293/_images/TWP33_012.jpg differ diff --git a/293/_images/TWP33_015.jpg b/293/_images/TWP33_015.jpg new file mode 100644 index 0000000000..788b1d9938 Binary files /dev/null and b/293/_images/TWP33_015.jpg differ diff --git a/293/_images/TWP33_016.jpg b/293/_images/TWP33_016.jpg new file mode 100644 index 0000000000..9a0e4e372a Binary files /dev/null and b/293/_images/TWP33_016.jpg differ diff --git a/293/_images/TWP33_018.jpg b/293/_images/TWP33_018.jpg new file mode 100644 index 0000000000..9ee4d6cd63 Binary files /dev/null and b/293/_images/TWP33_018.jpg differ diff --git a/293/_images/TWP33_025.jpg b/293/_images/TWP33_025.jpg new file mode 100644 index 0000000000..6bfa28acc1 Binary files /dev/null and b/293/_images/TWP33_025.jpg differ diff --git a/293/_images/TWP33_028.jpg b/293/_images/TWP33_028.jpg new file mode 100644 index 0000000000..cf42820c5b Binary files /dev/null and b/293/_images/TWP33_028.jpg differ diff --git a/293/_images/TWP33_029.jpg b/293/_images/TWP33_029.jpg new file mode 100644 index 0000000000..28f2f79de4 Binary files /dev/null and b/293/_images/TWP33_029.jpg differ diff --git a/293/_images/TWP33_030.jpg b/293/_images/TWP33_030.jpg new file mode 100644 index 0000000000..48ab80214e Binary files /dev/null and b/293/_images/TWP33_030.jpg differ diff --git a/293/_images/TWP33_032.jpg b/293/_images/TWP33_032.jpg new file mode 100644 index 0000000000..68f6097d79 Binary files /dev/null and b/293/_images/TWP33_032.jpg differ diff --git a/293/_images/TWP33_033.jpg b/293/_images/TWP33_033.jpg new file mode 100644 index 0000000000..491ef6ec63 Binary files /dev/null and b/293/_images/TWP33_033.jpg differ diff --git a/293/_images/TWP33_034.jpg b/293/_images/TWP33_034.jpg new file mode 100644 index 0000000000..bca87ebce3 Binary files /dev/null and b/293/_images/TWP33_034.jpg differ diff --git a/293/_images/TWP35_001.jpeg b/293/_images/TWP35_001.jpeg new file mode 100644 index 0000000000..ebf55f5bc5 Binary files /dev/null and b/293/_images/TWP35_001.jpeg differ diff --git a/293/_images/TWP35_002.jpeg b/293/_images/TWP35_002.jpeg new file mode 100644 index 0000000000..40b73a2c86 Binary files /dev/null and b/293/_images/TWP35_002.jpeg differ diff --git a/293/_images/TWP35_005.jpeg b/293/_images/TWP35_005.jpeg new file mode 100644 index 0000000000..1b9213dce2 Binary files /dev/null and b/293/_images/TWP35_005.jpeg differ diff --git a/293/_images/TWP37_001.jpeg b/293/_images/TWP37_001.jpeg new file mode 100644 index 0000000000..2c48095ff1 Binary files /dev/null and b/293/_images/TWP37_001.jpeg differ diff --git a/293/_images/TWP37_002.jpeg b/293/_images/TWP37_002.jpeg new file mode 100644 index 0000000000..6165afe6ae Binary files /dev/null and b/293/_images/TWP37_002.jpeg differ diff --git a/293/_images/TWP37_003.jpeg b/293/_images/TWP37_003.jpeg new file mode 100644 index 0000000000..16f2e1413b Binary files /dev/null and b/293/_images/TWP37_003.jpeg differ diff --git a/293/_images/TWP37_004.jpg b/293/_images/TWP37_004.jpg new file mode 100644 index 0000000000..54f673db5f Binary files /dev/null and b/293/_images/TWP37_004.jpg differ diff --git a/293/_images/TWP37_007.jpg b/293/_images/TWP37_007.jpg new file mode 100644 index 0000000000..e76a16474e Binary files /dev/null and b/293/_images/TWP37_007.jpg differ diff --git a/293/_images/TWP37_008.jpg b/293/_images/TWP37_008.jpg new file mode 100644 index 0000000000..cbdd1478e0 Binary files /dev/null and b/293/_images/TWP37_008.jpg differ diff --git a/293/_images/TWP37_010.jpg b/293/_images/TWP37_010.jpg new file mode 100644 index 0000000000..1965093211 Binary files /dev/null and b/293/_images/TWP37_010.jpg differ diff --git a/293/_images/TWP37_011.jpg b/293/_images/TWP37_011.jpg new file mode 100644 index 0000000000..373e0af6d5 Binary files /dev/null and b/293/_images/TWP37_011.jpg differ diff --git a/293/_images/TWP37_014.jpg b/293/_images/TWP37_014.jpg new file mode 100644 index 0000000000..23f0d3e855 Binary files /dev/null and b/293/_images/TWP37_014.jpg differ diff --git a/293/_images/TWP37_016.jpg b/293/_images/TWP37_016.jpg new file mode 100644 index 0000000000..e718ded0a7 Binary files /dev/null and b/293/_images/TWP37_016.jpg differ diff --git a/293/_images/TWP37_017.jpg b/293/_images/TWP37_017.jpg new file mode 100644 index 0000000000..5d8121ec99 Binary files /dev/null and b/293/_images/TWP37_017.jpg differ diff --git a/293/_images/TWP37_018.jpg b/293/_images/TWP37_018.jpg new file mode 100644 index 0000000000..3ee4c7889e Binary files /dev/null and b/293/_images/TWP37_018.jpg differ diff --git a/293/_images/TWP37_021.jpg b/293/_images/TWP37_021.jpg new file mode 100644 index 0000000000..80fb112a1b Binary files /dev/null and b/293/_images/TWP37_021.jpg differ diff --git a/293/_images/TWP37_022.jpg b/293/_images/TWP37_022.jpg new file mode 100644 index 0000000000..9a7c742779 Binary files /dev/null and b/293/_images/TWP37_022.jpg differ diff --git a/293/_images/TWP37_025.jpg b/293/_images/TWP37_025.jpg new file mode 100644 index 0000000000..24a9732fdd Binary files /dev/null and b/293/_images/TWP37_025.jpg differ diff --git a/293/_images/TWP37_026.png b/293/_images/TWP37_026.png new file mode 100644 index 0000000000..711f26724a Binary files /dev/null and b/293/_images/TWP37_026.png differ diff --git a/293/_images/TWP37_027.png b/293/_images/TWP37_027.png new file mode 100644 index 0000000000..0d88771a99 Binary files /dev/null and b/293/_images/TWP37_027.png differ diff --git a/293/_images/TWP42_003.jpeg b/293/_images/TWP42_003.jpeg new file mode 100644 index 0000000000..efd09f6890 Binary files /dev/null and b/293/_images/TWP42_003.jpeg differ diff --git a/293/_images/TWP42_004.jpeg b/293/_images/TWP42_004.jpeg new file mode 100644 index 0000000000..f29a264ca7 Binary files /dev/null and b/293/_images/TWP42_004.jpeg differ diff --git a/293/_images/TWP42_005.jpeg b/293/_images/TWP42_005.jpeg new file mode 100644 index 0000000000..d4066bf7ca Binary files /dev/null and b/293/_images/TWP42_005.jpeg differ diff --git a/293/_images/TWP42_009.png b/293/_images/TWP42_009.png new file mode 100644 index 0000000000..c4c4d958f5 Binary files /dev/null and b/293/_images/TWP42_009.png differ diff --git a/293/_images/TWP45_001.jpeg b/293/_images/TWP45_001.jpeg new file mode 100644 index 0000000000..fe6c245273 Binary files /dev/null and b/293/_images/TWP45_001.jpeg differ diff --git a/293/_images/TWP45_002.jpeg b/293/_images/TWP45_002.jpeg new file mode 100644 index 0000000000..72a5050b5b Binary files /dev/null and b/293/_images/TWP45_002.jpeg differ diff --git a/293/_images/TWP45_050.png b/293/_images/TWP45_050.png new file mode 100644 index 0000000000..04f3c6bb4c Binary files /dev/null and b/293/_images/TWP45_050.png differ diff --git a/293/_images/TWP47_001.png b/293/_images/TWP47_001.png new file mode 100644 index 0000000000..a6070d1eee Binary files /dev/null and b/293/_images/TWP47_001.png differ diff --git a/293/_images/TWP47_002.png b/293/_images/TWP47_002.png new file mode 100644 index 0000000000..985f2a3909 Binary files /dev/null and b/293/_images/TWP47_002.png differ diff --git a/293/_images/TWP47_004.jpg b/293/_images/TWP47_004.jpg new file mode 100644 index 0000000000..c595f60f52 Binary files /dev/null and b/293/_images/TWP47_004.jpg differ diff --git a/293/_images/TWP47_005.png b/293/_images/TWP47_005.png new file mode 100644 index 0000000000..18870f396b Binary files /dev/null and b/293/_images/TWP47_005.png differ diff --git a/293/_images/TWP47_006.png b/293/_images/TWP47_006.png new file mode 100644 index 0000000000..e5a27fb25e Binary files /dev/null and b/293/_images/TWP47_006.png differ diff --git a/293/_images/TWP47_007.png b/293/_images/TWP47_007.png new file mode 100644 index 0000000000..bc2172eedd Binary files /dev/null and b/293/_images/TWP47_007.png differ diff --git a/293/_images/TWP47_008.jpg b/293/_images/TWP47_008.jpg new file mode 100644 index 0000000000..de8734e697 Binary files /dev/null and b/293/_images/TWP47_008.jpg differ diff --git a/293/_images/TWP47_011.jpg b/293/_images/TWP47_011.jpg new file mode 100644 index 0000000000..bcc52991ce Binary files /dev/null and b/293/_images/TWP47_011.jpg differ diff --git a/293/_images/TWP47_015.png b/293/_images/TWP47_015.png new file mode 100644 index 0000000000..6a901cd9fc Binary files /dev/null and b/293/_images/TWP47_015.png differ diff --git a/293/_images/TWP47_017.png b/293/_images/TWP47_017.png new file mode 100644 index 0000000000..d847b0ba40 Binary files /dev/null and b/293/_images/TWP47_017.png differ diff --git a/293/_images/TWP47_018.png b/293/_images/TWP47_018.png new file mode 100644 index 0000000000..fc1b6aaa7e Binary files /dev/null and b/293/_images/TWP47_018.png differ diff --git a/293/_images/TWP47_020.png b/293/_images/TWP47_020.png new file mode 100644 index 0000000000..88f4f10bfc Binary files /dev/null and b/293/_images/TWP47_020.png differ diff --git a/293/_images/TWP47_021.png b/293/_images/TWP47_021.png new file mode 100644 index 0000000000..763241a8eb Binary files /dev/null and b/293/_images/TWP47_021.png differ diff --git a/293/_images/TWP50_003.png b/293/_images/TWP50_003.png new file mode 100644 index 0000000000..b73170ed54 Binary files /dev/null and b/293/_images/TWP50_003.png differ diff --git a/293/_images/TWP50_004.png b/293/_images/TWP50_004.png new file mode 100644 index 0000000000..0f3888a7de Binary files /dev/null and b/293/_images/TWP50_004.png differ diff --git a/293/_images/TWP50_006.png b/293/_images/TWP50_006.png new file mode 100644 index 0000000000..61cc300138 Binary files /dev/null and b/293/_images/TWP50_006.png differ diff --git a/293/_images/TWP50_007.jpg b/293/_images/TWP50_007.jpg new file mode 100644 index 0000000000..f74e4d385d Binary files /dev/null and b/293/_images/TWP50_007.jpg differ diff --git a/293/_images/TWP50_008.jpg b/293/_images/TWP50_008.jpg new file mode 100644 index 0000000000..87e351f0d7 Binary files /dev/null and b/293/_images/TWP50_008.jpg differ diff --git a/293/_images/TWP50_013.jpg b/293/_images/TWP50_013.jpg new file mode 100644 index 0000000000..99acd65454 Binary files /dev/null and b/293/_images/TWP50_013.jpg differ diff --git a/293/_images/TWP50_017.jpg b/293/_images/TWP50_017.jpg new file mode 100644 index 0000000000..93706b9a3b Binary files /dev/null and b/293/_images/TWP50_017.jpg differ diff --git a/293/_images/TWP52_001.jpg b/293/_images/TWP52_001.jpg new file mode 100644 index 0000000000..94c0244579 Binary files /dev/null and b/293/_images/TWP52_001.jpg differ diff --git a/293/_images/TWP52_005.jpg b/293/_images/TWP52_005.jpg new file mode 100644 index 0000000000..2af0c18a67 Binary files /dev/null and b/293/_images/TWP52_005.jpg differ diff --git a/293/_images/TWP52_006.jpg b/293/_images/TWP52_006.jpg new file mode 100644 index 0000000000..7fb31bddd1 Binary files /dev/null and b/293/_images/TWP52_006.jpg differ diff --git a/293/_images/TWP52_007.png b/293/_images/TWP52_007.png new file mode 100644 index 0000000000..568b4ec94a Binary files /dev/null and b/293/_images/TWP52_007.png differ diff --git a/293/_images/TWP52_008.jpg b/293/_images/TWP52_008.jpg new file mode 100644 index 0000000000..157b168546 Binary files /dev/null and b/293/_images/TWP52_008.jpg differ diff --git a/293/_images/TWP52_009.jpg b/293/_images/TWP52_009.jpg new file mode 100644 index 0000000000..02ac8f347a Binary files /dev/null and b/293/_images/TWP52_009.jpg differ diff --git a/293/_images/TWP52_013.jpg b/293/_images/TWP52_013.jpg new file mode 100644 index 0000000000..228fbf6f4c Binary files /dev/null and b/293/_images/TWP52_013.jpg differ diff --git a/293/_images/TWP52_014.png b/293/_images/TWP52_014.png new file mode 100644 index 0000000000..3e6e2822b8 Binary files /dev/null and b/293/_images/TWP52_014.png differ diff --git a/293/_images/TWP52_016.jpg b/293/_images/TWP52_016.jpg new file mode 100644 index 0000000000..23279a8157 Binary files /dev/null and b/293/_images/TWP52_016.jpg differ diff --git a/293/_images/TWP52_017.png b/293/_images/TWP52_017.png new file mode 100644 index 0000000000..dc9ec1e17b Binary files /dev/null and b/293/_images/TWP52_017.png differ diff --git a/293/_images/TWP52_020.jpg b/293/_images/TWP52_020.jpg new file mode 100644 index 0000000000..928faea787 Binary files /dev/null and b/293/_images/TWP52_020.jpg differ diff --git a/293/_images/TWP54_001.jpg b/293/_images/TWP54_001.jpg new file mode 100644 index 0000000000..6b5e65d4f7 Binary files /dev/null and b/293/_images/TWP54_001.jpg differ diff --git a/293/_images/TWP54_002.jpg b/293/_images/TWP54_002.jpg new file mode 100644 index 0000000000..f44690146e Binary files /dev/null and b/293/_images/TWP54_002.jpg differ diff --git a/293/_images/TWP54_003.jpg b/293/_images/TWP54_003.jpg new file mode 100644 index 0000000000..1cecb4cc8e Binary files /dev/null and b/293/_images/TWP54_003.jpg differ diff --git a/293/_images/TWP54_004.jpg b/293/_images/TWP54_004.jpg new file mode 100644 index 0000000000..0fafbb23d4 Binary files /dev/null and b/293/_images/TWP54_004.jpg differ diff --git a/293/_images/TWP54_005.jpg b/293/_images/TWP54_005.jpg new file mode 100644 index 0000000000..16c3578f5b Binary files /dev/null and b/293/_images/TWP54_005.jpg differ diff --git a/293/_images/TWP54_007.jpg b/293/_images/TWP54_007.jpg new file mode 100644 index 0000000000..3e27854c82 Binary files /dev/null and b/293/_images/TWP54_007.jpg differ diff --git a/293/_images/TWP54_009.jpg b/293/_images/TWP54_009.jpg new file mode 100644 index 0000000000..035283f930 Binary files /dev/null and b/293/_images/TWP54_009.jpg differ diff --git a/293/_images/TWP54_010.jpg b/293/_images/TWP54_010.jpg new file mode 100644 index 0000000000..9a12440606 Binary files /dev/null and b/293/_images/TWP54_010.jpg differ diff --git a/293/_images/TWP56_001.jpg b/293/_images/TWP56_001.jpg new file mode 100644 index 0000000000..d771da152b Binary files /dev/null and b/293/_images/TWP56_001.jpg differ diff --git a/293/_images/TWP56_003.jpg b/293/_images/TWP56_003.jpg new file mode 100644 index 0000000000..c6864ebf44 Binary files /dev/null and b/293/_images/TWP56_003.jpg differ diff --git a/293/_images/TWP56_005.jpg b/293/_images/TWP56_005.jpg new file mode 100644 index 0000000000..9ec9d8049d Binary files /dev/null and b/293/_images/TWP56_005.jpg differ diff --git a/293/_images/TWP56_008.jpg b/293/_images/TWP56_008.jpg new file mode 100644 index 0000000000..2af3bcfa9b Binary files /dev/null and b/293/_images/TWP56_008.jpg differ diff --git a/293/_images/TWP56_010.jpg b/293/_images/TWP56_010.jpg new file mode 100644 index 0000000000..ca57f21beb Binary files /dev/null and b/293/_images/TWP56_010.jpg differ diff --git a/293/_images/TWP58_002.jpeg b/293/_images/TWP58_002.jpeg new file mode 100644 index 0000000000..8034f0d60a Binary files /dev/null and b/293/_images/TWP58_002.jpeg differ diff --git a/293/_images/TWP58_003.jpg b/293/_images/TWP58_003.jpg new file mode 100644 index 0000000000..126c05228a Binary files /dev/null and b/293/_images/TWP58_003.jpg differ diff --git a/293/_images/TWP58_004.jpg b/293/_images/TWP58_004.jpg new file mode 100644 index 0000000000..5b1a00b8be Binary files /dev/null and b/293/_images/TWP58_004.jpg differ diff --git a/293/_images/TWP58_005.jpg b/293/_images/TWP58_005.jpg new file mode 100644 index 0000000000..396fd77d7b Binary files /dev/null and b/293/_images/TWP58_005.jpg differ diff --git a/293/_images/TWP58_006.jpg b/293/_images/TWP58_006.jpg new file mode 100644 index 0000000000..4973b0cb64 Binary files /dev/null and b/293/_images/TWP58_006.jpg differ diff --git a/293/_images/TWP58_007.jpg b/293/_images/TWP58_007.jpg new file mode 100644 index 0000000000..45cea01104 Binary files /dev/null and b/293/_images/TWP58_007.jpg differ diff --git a/293/_images/TWP58_010.png b/293/_images/TWP58_010.png new file mode 100644 index 0000000000..55c73f2c6a Binary files /dev/null and b/293/_images/TWP58_010.png differ diff --git a/293/_images/TWP58_011.png b/293/_images/TWP58_011.png new file mode 100644 index 0000000000..7ece8616e8 Binary files /dev/null and b/293/_images/TWP58_011.png differ diff --git a/293/_images/TWP60_001.jpeg b/293/_images/TWP60_001.jpeg new file mode 100644 index 0000000000..37b807a39b Binary files /dev/null and b/293/_images/TWP60_001.jpeg differ diff --git a/293/_images/TWP60_002.jpeg b/293/_images/TWP60_002.jpeg new file mode 100644 index 0000000000..4d3dca233e Binary files /dev/null and b/293/_images/TWP60_002.jpeg differ diff --git a/293/_images/TWP60_005.png b/293/_images/TWP60_005.png new file mode 100644 index 0000000000..6948c20b79 Binary files /dev/null and b/293/_images/TWP60_005.png differ diff --git a/293/_images/TWP60_007.png b/293/_images/TWP60_007.png new file mode 100644 index 0000000000..e89ab6efc2 Binary files /dev/null and b/293/_images/TWP60_007.png differ diff --git a/293/_images/TWP60_008.png b/293/_images/TWP60_008.png new file mode 100644 index 0000000000..4120db4551 Binary files /dev/null and b/293/_images/TWP60_008.png differ diff --git a/293/_images/TWP60_014.png b/293/_images/TWP60_014.png new file mode 100644 index 0000000000..bbdd829d70 Binary files /dev/null and b/293/_images/TWP60_014.png differ diff --git a/293/_images/TWP60_015.png b/293/_images/TWP60_015.png new file mode 100644 index 0000000000..bc80fa0fed Binary files /dev/null and b/293/_images/TWP60_015.png differ diff --git a/293/_images/TWP60_017.png b/293/_images/TWP60_017.png new file mode 100644 index 0000000000..8d4323813c Binary files /dev/null and b/293/_images/TWP60_017.png differ diff --git a/293/_images/TWP60_022.png b/293/_images/TWP60_022.png new file mode 100644 index 0000000000..3f23134457 Binary files /dev/null and b/293/_images/TWP60_022.png differ diff --git a/293/_images/TWP60_023.png b/293/_images/TWP60_023.png new file mode 100644 index 0000000000..49379a8fea Binary files /dev/null and b/293/_images/TWP60_023.png differ diff --git a/293/_images/TWP65_001.jpg b/293/_images/TWP65_001.jpg new file mode 100644 index 0000000000..7902cecd35 Binary files /dev/null and b/293/_images/TWP65_001.jpg differ diff --git a/293/_images/TWP65_002.jpg b/293/_images/TWP65_002.jpg new file mode 100644 index 0000000000..26046e90aa Binary files /dev/null and b/293/_images/TWP65_002.jpg differ diff --git a/293/_sources/challenges/Reto01.rst.txt b/293/_sources/challenges/Reto01.rst.txt new file mode 100644 index 0000000000..1ebf6c3349 --- /dev/null +++ b/293/_sources/challenges/Reto01.rst.txt @@ -0,0 +1,340 @@ +============= +Reto Ahorcado +============= + +Este reto consiste en crear el juego de **ahorcado** a partir de código Python. + +.. tabbed:: ahorcado + + .. tab:: Ejercicio 1 + + Primero haremos los distintos dibujos del ahorcado con cadenas de texto. + + .. activecode:: ac_r01_1 + :nocodelens: + + En la lista ``dibujos`` colocaremos las cadenas de texto que representan + los dibujos del ahorcado. + + ~~~~ + dibujos = [ + """ + +------+ + | + | + | + | + | + +--------+ """, + """ + +------+ + | | + | + | + | + | + +--------+ """, + """ + +------+ + | | + o | + | + | + | + +--------+ """, + """ + +------+ + | | + o | + | | + | + | + +--------+ """, + """ + +------+ + | | + o | + /| | + | + | + +--------+ """, + """ + +------+ + | | + o | + /|\ | + | + | + +--------+ """, + """ + +------+ + | | + o | + /|\ | + / | + | + +--------+ """, + """ + +------+ + | | + o | + /|\ | + / \ | + | + +--------+ """, + ] + + + .. tab:: Ejercicio 2 + + Va a resolver el reto de manera progresiva. + + .. activecode:: ac_r01_2 + :nocodelens: + + Cree dos variables, una llamada ``correctas`` y la otra ``incorrectas``. Ambas asígnelas a + una cadena vacía. + + ~~~~ + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(correctas, "", "Probando que correctas esté asignada correctamente") + self.assertEqual(incorrectas, "", "Probando que incorrectas esté asignada correctamente") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + ¿Recuerda la lección de las APIs? Vamos a aplicar lo aprendido de esa lección. + + .. activecode:: ac_r01_3 + :nocodelens: + + Para poder jugar ahorcado necesitamos palabras para adivinar. En este caso vamos a + recuperar esas palabras de la API de University Domains. Estas palabras serán ciudades + del mundo. + Con la librería ``requests`` acceda a la API de University Domains. La url es la siguiente + http://universities.hipolabs.com/search + Desarrolle la función ``escoger`` que escoja de manera **aleatoria** una ciudad dentro de las ciudades de la + lista ``ciudades``. Esta ciudad será devuelta por la función. Cabe aclarar que el nombre de cada ciudad + está en inglés. + + ~~~~ + import requests + import json + from random import choice + + api_url = "http://universities.hipolabs.com/search" + + solicitud = requests.get(api_url) + datos = json.loads(solicitud.text) + + ciudades = [] + for universidad in datos: + if universidad["country"] not in ciudades: + ciudades.append(universidad["country"].lower().replace(" ", "")) + + def escoger(ciudades): + # Desarrolle la función + # Se puede lograr con una sola línea de código + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(str(type(escoger)), "", "Probando que escoger haya sido definida") + self.assertEqual(escoger(["Mexico"]), "Mexico", "Probando que la función sirva") + self.assertEqual(choice([2]), 2, "Probando que choice haya sido importado") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + Ahora definamos otra función para imprimir el ahorcado. + + .. activecode:: ac_r01_4 + :nocodelens: + :include: ac_r01_1, ac_r01_2, ac_r01_3 + + La función ``imprimir_ahorcado`` imprime el dibujo del ahorcado correspondiente al + número de letras incorrectas y correctas hasta el momento. Toma un único parámetro + ``p_aleatoria`` que representa la palabra a adivinar. + + ~~~~ + p_aleatoria = escoger(ciudades) + def imprimir_ahorcado(p_aleatoria): + print(dibujos[len(incorrectas)]) + for c in p_aleatoria: + print(c if c in correctas else "_", end=" ") + print() + + + .. tab:: Ejercicio 5 + + Es momento de crear la función principal de nuestro programa, la cuál pide al usuario una + letra para adivinar. + + .. activecode:: ac_r01_5 + :nocodelens: + + Desarrolle la función ``adivinar``. Recibe como parámetro una cadena (``letras``) con todas las letras ya + probadas (correctas + incorrectas). Devuelve una letra minúscula que no se ha probado antes. + Si el usuario ingresa más de una letra u otro carácter especial, se debe imprimir un mensaje + alertando al usuario de su error. Por ejemplo: ``"Caracter inválido"`` + Esta función tendrá un bucle que hará que todos los datos sean coherentes y solo pasará + a tu programa principal la letra minúscula que no se probó antes. Guarde lo ingresado por el usuario en la + variable ``x``. **Nota**: La función se va a ejecutar una vez y pedirá que se ingrese una letra + para verificar si pasa las pruebas unitarias. + + ~~~~ + from string import digits, punctuation + import time + + def adivinar(letras): + while True: + x = # Empiece aquí + + # Todo su código debe ir dentro de este ciclo while + + # Esperar antes de preguntar por un input de nuevo + # No remover esta línea de código + time.sleep(2) + + + ==== + from unittest.gui import TestCaseGui + import string + + + class myTests(TestCaseGui): + def testOne(self): + x = adivinar("aeiou") + self.assertEqual(x in string.ascii_lowercase, True, "Probando que x haya sido devuelto correctamente") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + Hagamos posible que el usuario decida si quiere volver a jugar o no. + + .. activecode:: ac_r01_6 + :nocodelens: + + Desarrolle la función ``jugar_nuevamente`` que pregunte al usuario si quiere volver a + jugar. La respuesta debe ser una *s* o *n* (S/N). Sin importar si el usuario ingresa la respuesta + en mayúscula o minúscula, el programa debe transformarla a minúscula. La función devuelve ``True`` o ``False`` + dependiendo de la respuesta. **Nota**: La función se va a ejecutar dos veces para verificar si pasa las pruebas unitarias. + En la consola verá instrucciones sobre qué ingresar para cada prueba. + + ~~~~ + def jugar_nuevamente(): + + return + + + ==== + from unittest.gui import TestCaseGui + import time + + + class myTests(TestCaseGui): + def testOne(self): + print("Ingrese 'S'") + time.sleep(2) + r = jugar_nuevamente() + self.assertEqual(r, True, "Probando que se haya utilizado el método lower") + + + def testTwo(self): + print("Ingrese 'n'") + time.sleep(2) + r = jugar_nuevamente() + self.assertEqual(r, False, "Probando que al ingresar 'n' regrese False") + + + myTests().main() + + + .. tab:: Ejercicio 7 + + .. activecode:: ac_r01_7 + :nocodelens: + + Ahora desarrolle la función ``ganar``. Ésta toma dos parámetros: ``p_aleatoria`` que representa + la palabra a adivinar, y ``letras_adivinadas``. Debe devolver ``True`` si todas las letras de + ``p_aleatoria`` están en la cadena ``letras_adivinadas``. De lo contrario, devuelve False. + + ~~~~ + def ganar(p_aleatoria, letras_adivinadas): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(ganar("argentina", "anitnegra"), True, "Probando la función") + self.assertEqual(ganar("argentina", "argent"), False, "Probando la función") + + + myTests().main() + + .. tab:: Ejercicio 8 + + Ya ha definido todas las funciones y variables necesarias para el programa. Si ha llegado hasta aquí, + debió haber cumplido con todo y haber pasado todas las pruebas unitarias. De ser así, puede correr el + siguiente programa para probar su juego. El tiempo que tiene para jugar son 5 minutos. + + .. activecode:: ac_r01_8 + :nocodelens: + :include: ac_r01_1, ac_r01_2, ac_r01_3, ac_r01_4, ac_r01_5, ac_r01_6, ac_r01_7 + + # Esto nos sirve para aumentar la duración del programa a 5 minutos. + import sys + sys.setExecutionLimit(300000) + + p_aleatoria = escoger(ciudades) + + while True: + imprimir_ahorcado(p_aleatoria) + time.sleep(2) + x = adivinar(correctas + incorrectas) + if x in p_aleatoria: + correctas = correctas + x + else: + incorrectas = incorrectas + x + if len(incorrectas) == len(dibujos): + print(f"Quedó ahorcado, la palabra era {p_aleatoria}") + time.sleep(1) + if jugar_nuevamente(): + correctas = incorrectas = "" + p_aleatoria = escoger(ciudades) + else: + break + elif ganar(p_aleatoria, correctas): + print(f"Acertó la palabra: {p_aleatoria}") + time.sleep(1) + if jugar_nuevamente(): + correctas = incorrectas = "" + p_aleatoria = escoger(ciudades) + else: + break + + ==== diff --git a/293/_sources/challenges/Reto01_en.rst.txt b/293/_sources/challenges/Reto01_en.rst.txt new file mode 100644 index 0000000000..bfa2cde412 --- /dev/null +++ b/293/_sources/challenges/Reto01_en.rst.txt @@ -0,0 +1,333 @@ +================= +Hangman Challenge +================= + +This challenge consists in creating the **hangman** game from Python code. + +.. tabbed:: hangman + + .. tab:: Exercise 1 + + First, we'll make the different hangman drawings with text strings. + + .. activecode:: ac_r01_1_en + :nocodelens: + + In the ``drawings`` list we will place the text strings that represent + the hangman drawings. + + ~~~~ + drawings = [ + """ + +------+ + | + | + | + | + | + +--------+ """, + """ + +------+ + | | + | + | + | + | + +--------+ """, + """ + +------+ + | | + o | + | + | + | + +--------+ """, + """ + +------+ + | | + o | + | | + | + | + +--------+ """, + """ + +------+ + | | + o | + /| | + | + | + +--------+ """, + """ + +------+ + | | + o | + /|\\ | + | + | + +--------+ """, + """ + +------+ + | | + o | + /|\\ | + / | + | + +--------+ """, + """ + +------+ + | | + o | + /|\\ | + / \\ | + | + +--------+ """, + ] + + + .. tab:: Exercise 2 + + We will solve the challenge progressively. + + .. activecode:: ac_r01_2_en + :nocodelens: + + Create two variables, one called "correct" and the other "incorrect". Both should be assigned to + an empty string. + + ~~~~ + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(correct, "", "Testing that correct is assigned correctly") + self.assertEqual(incorrect, "", "Testing that incorrect is assigned correctly") + + + myTests().main() + + + .. tab:: Exercise 3 + + Do you remember the lesson on APIs? Let's apply what we learned from that lesson. + + .. activecode:: ac_r01_3_en + :nocodelens: + + To play hangman we need words to guess. In this case we will retrieve those words from the University Domains API. + These words will be world cities. + Use the ``requests`` library to access the University Domains API. The url is the following + http://universities.hipolabs.com/search + Develop the ``choose`` function that will **randomly** choose a city within the cities of the + ``cities`` list. This city will be returned by the function. It should be noted that the name of each city + is given in English. + + ~~~~ + import requests + import json + from random import choice + + api_url = "http://universities.hipolabs.com/search" + + solicitation = requests.get(api_url) + data = json.loads(solicitation.text) + + cities = [] + for university in data: + if university["country"] not in cities: + cities.append(university["country"].lower().replace(" ", "")) + + def choose(cities): + # Develop the function + # It can be achieved with a single line of code + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(str(type(choose)), "", "Testing that choose has been defined") + self.assertEqual(choose(["Mexico"]), "Mexico", "Testing that the function works") + self.assertEqual(choice([2]), 2, "Testing that choice has been imported") + + + myTests().main() + + + .. tab:: Exercise 4 + + Let's define another function to print the hangman. + + .. activecode:: ac_r01_4_en + :nocodelens: + :include: ac_r01_1_en, ac_r01_2_en, ac_r01_3_en + + The ``print_hangman`` function prints the corresponding hangman drawing according to + the number of correct and incorrect letters so far. It takes a single parameter + ``p_aleatoria`` which represents the word to guess. + + ~~~~ + p_aleatoria = choose(cities) + def print_hangman(p_aleatoria): + print(drawings[len(incorrect)]) + for c in p_aleatoria: + print(c if c in correct else "_", end=" ") + print() + + + .. tab:: Exercise 5 + + It's time to create the main function of our program, which asks the user for a + letter to guess. + + .. activecode:: ac_r01_5_en + :nocodelens: + + Develop the ``guess`` function. It receives a string as a parameter (``letters``) with all the letters already + tested (correct + incorrect). It returns a lowercase letter that has not been tested before. + If the user enters more than one letter or another special character, a message should be printed + alerting the user of their error. For example: ``"Invalid character"`` + This function will have a loop that will make sure that all the data is coherent and will only pass + to the main program the lowercase letter that has not been already tested. Save what the user enters in the + variable ``x``. **Note**: The function will be run once and will ask for a letter to verify if the unit tests pass. + + ~~~~ + from string import digits, punctuation + import time + + def guess(letters): + while True: + x = # Start here + + # All your code must go inside this while loop + + # Wait before asking for input again + # Do not remove this line of code + time.sleep(2) + + + ==== + from unittest.gui import TestCaseGui + import string + + + class myTests(TestCaseGui): + def testOne(self): + x = guess("aeiou") + self.assertEqual(x in string.ascii_lowercase, True, "Testing that x has been returned correctly") + + + myTests().main() + + + .. tab:: Exercise 6 + + Let's make it possible for the user to decide whether or not they want to play again. + + .. activecode:: ac_r01_6_en + :nocodelens: + + Develop the ``play_again`` function that asks the user if they want to play again. The answer should be *s* or *n* (S/N). + Regardless of whether the user enters the response in uppercase or lowercase, the program should transform it to lowercase. + The function returns ``True`` or ``False`` depending on the response. **Note**: The function will be run twice to check if it passes the unit tests. + In the console, you will see instructions on what to enter for each test. + + ~~~~ + def play_again(): + + return + + + ==== + from unittest.gui import TestCaseGui + import time + + + class myTests(TestCaseGui): + def testOne(self): + print("Enter 'S'") + time.sleep(2) + r = play_again() + self.assertEqual(r, True, "Testing that the lower method has been used") + + + def testTwo(self): + print("Enter 'n'") + time.sleep(2) + r = play_again() + self.assertEqual(r, False, "Testing that it returns False when entering 'n'") + + + myTests().main() + + + .. tab:: Exercise 7 + + .. activecode:: ac_r01_7_en + :nocodelens: + + Now develop the ``win`` function. It takes two parameters: ``p_aleatoria``, which represents the word to be guessed, and ``letras_adivinadas``. It should return ``True`` if all the letters of ``p_aleatoria`` are in the ``letras_adivinadas`` string. Otherwise, it returns False. + + ~~~~ + def win(p_aleatoria, letras_adivinadas): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(win("argentina", "anitnegra"), True, "Testing function") + self.assertEqual(win("argentina", "argent"), False, "Testing function") + + + myTests().main() + + .. tab:: Exercise 8 + + You have already defined all the necessary functions and variables for the program. If you have made it this far, you should have completed everything and passed all the unit tests. If so, you can run the following program to test your game. You have 5 minutes to play. + + .. activecode:: ac_r01_8_en + :nocodelens: + :include: ac_r01_1_en, ac_r01_2_en, ac_r01_3_en, ac_r01_4_en, ac_r01_5_en, ac_r01_6_en, ac_r01_7_en + + # This helps to increase the program duration to 5 minutes + import sys + sys.setExecutionLimit(300000) + + p_aleatoria = choose(cities) + + while True: + print_hangman(p_aleatoria) + time.sleep(2) + x = guess(correct + incorrect) + if x in p_aleatoria: + correct = correct + x + else: + incorrect = incorrect + x + if len(incorrect) == len(drawings): + print(f"You were hanged, the word was {p_aleatoria}") + time.sleep(1) + if play_again(): + correct = incorrect = "" + p_aleatoria = choose(cities) + else: + break + elif win(p_aleatoria, correct): + print(f"You guessed the word: {p_aleatoria}") + time.sleep(1) + if play_again(): + correct = incorrect = "" + p_aleatoria = choose(cities) + else: + break + + ==== \ No newline at end of file diff --git a/293/_sources/challenges/Reto02.rst.txt b/293/_sources/challenges/Reto02.rst.txt new file mode 100644 index 0000000000..670dc677c5 --- /dev/null +++ b/293/_sources/challenges/Reto02.rst.txt @@ -0,0 +1,294 @@ +============== +Reto Pergamino +============== + +Este reto consiste en descifrar un pergamino a partir de código Python + +.. tabbed:: pergamino + + .. tab:: Ejercicio 1 + + Primero veamos la estructura de los textos del pergamino. + + .. activecode:: ac_r02_1 + :nocodelens: + + Arqueólogos encontraron un pergamino con los siguientes textos: ``txt_A`` y ``txt_B``. + + ~~~~ + txt_A = '''cncdbm pjcjzct vdbbxdtw rfqsr mkt gvhkcsvw qcxr kmk pnhc zwwdsd pgjjhr + lxzscps lmbjjx lgh mdcqlbwx ppzpvfbv vdszkb njv nvmfhshh ztvkmv dfbnht xfpj nlbcwrvv + dcrzslrf wzb krdb zndtfmf fwwm vmqzmg cpcnpnww nkjk ncrmzr jfmcl hxr vcj wcptgbc + gvbfxtbv wcjlrs psjc lrljqdct ltjwn vmhp wnlmw rkvg rtm djsv rwjls ngc zcjjttpt kbg + tdjzcwj pmgtzlng zvtnbs svztn pctgq qnghqcch mclvp qdht cbk lvqckrl qmwknt cqw jfxzx + tkljpkfc mjhskxjh lfjvrhr whshcrk kvtgzpl gxglr mpqxtbzb zbrpktxj knhmmtks mhj xdlsm + wcc sbrkdjmh gpn vwddsdl mqfsrwt khhmfng qkkjgg qdr qlpt njq xlc jfhhv kgzsb lqncvrh + jgw xhjk krprtxf dtrsfb rwtzbhs qbvvz nqbh pdfqlsv hhrrx pvf mdvcfqkt bsb gcnkszfk + rkzlhbnx njfqrzxj gtvrwp cmgp qddg gqjjcbjw khlbtg cdswmbgb lmbfvsv nfhvn jbnplx gkh + dmp hmnf bzrznlh vqdmjdsb ktbcx fgvsxzp gmv xftg lxtf dcxsrkl tzwvbkfq tpvdrlf khzzw + srtfttv lmknq jvkwr bplzzpjw rgtrj gcmdfzdx ksptr jzdfqq xmtzz pkqxrsw gvwg fqppvgk hsc + hdj gthkq trxl gkhp rbr skxpc lbkw bbdqpvn llshm bhrfvh gjw zgnlpgwl pdhqn ttjtx vfb + djftp kkrr ptmnzqkg tmjlqw pcvpwjb ggd jntktdz vth wtsp mlfmddsn phn hrdqrds phbq + vkffrqvt zxljnd lqg blnw brxk skwkh vqbq dlbnhz xpbddsjw gscvghmj pxcpvkmm jsfpllns + kpmmgxb pljpvcn wknwbcq wthwv bdjxr wdc lqmtsnrn wbcjprr htldnxcn qwl fvjdqd cwmb bfjmw + chv blx xblfrb gjbbg njqw mkmnwtzv dgsxl tgtclv xxcfpp brzxg lbrnrsf pfcpt wmvjxdsw + jmstqwx zjcrkzm ndtbsqsh jqbcddqh ggvf kcr mfhllb lbbkssx gsrxcb rwtxljp cwkc xwxjhbc + pfcgz zbdbsq wzfsf gqhdfchv cgp kwvnrfm ptmzl bkjcm dpl rskfms mqdgvskt hbtjpvm swff + vjq dwlrgxtm kqzrlxz vmpdxkv bwfgzmjn zzrr mlsm kknhkq jhtxc gjvnj mcld vftnnd pgbkhc + kzzsbq xqbs hlkxtc xgj vttn zmnc kwhcrd bfjbs lxkmnzx pbmp lnt ztm fkzql bjgllxv + bghqpnl hphvdvl lwlqdh xldsnqds tsmrhhtm gnksf lzhr rqm jvcmkbxv nsx cxpplqbq jzrr tnt + wpfl lnkfqjt tplwbr hzrv mxqhpg xxzdlwzx cgrtr jbvqmb cmsqdjx qcrx ljxh jbnw lgf tzd + cltdd jtmdmt djbgqqk tgsffh hbff jjqn wtlsx qlmhxrrf sklfrc dwsk rgpgqz zhzvm brprszrc + hqlgx tdbsgf fkmrtn frskk qjvg jlhpgh rxrmqp nmc dxpx lljs kszjq hlxx nbkvsrf dggshkxz + nlvgr zldk tvphkg hlnls wlsxsvf mmksm lzgfnkmg tbw nrpzqfr gfc sxcdqtlt rmmhtmbp jkk + fdh jcw nwjjkrdq kztrcqxt lphf frs dcsbhwp tgnq lmq tpppxf vmd tnbqgv xxtlt ljdz hdslhv + dkzxctcn qsfctn tdsbdhv dxmkk ghfntj dckqls knlwvk mrddntg fwqwfxs tzqcvz sbnfjs kcxl + dsgnhsf kgj mfm vjmmf wptc rtb dtblv frp wwmngbk dxss txz fzlxll lbqjrp hhcxnnhn + skhcwxw lllkssb dgwd lzq czhhtclr bpngkf krh bzccxd rqkr mdz phk dfctpgr gkt bdnfbh wlj + lfhkmb crbhzfs qzz jbmlsfkx htkmdbx mxjccgv fpj ttl jbw pmnt khqr jhztz dvmj kwchwcv + xggzgkln dxz fdsfsc cgpn pphslgf jxsd fsp spzzbc trvpx wjg nmdzgmnr qslm znngdwb zqwb + dcgxxcqm kcdwcpdm ngqzs sbst ltqxkt tjgmjzh nmmqnzfn ngsbphqb gsqfgjn jtwhxdx pqc jsfkd + ccx dfj wrgf kslnx zgqxqpvm rflzw jgl rsd fshm zlmtqs qfbrdg dknttlb xvqnd gtrpzhwb + ngwrbrfk skkfq bzfqkpjj rzp trzz fgmcd ptg wzg mdxlzvkg rfqdh lvwht vkvqhk pdnqm gwpcph + qbpsv vhxdj vxf tvpjwzb tjpdp frtvg xrqhp zjqcbxf fpbwbzb whnjkv dqfjwtv mjwrncd xvgkv + xrsrjv zdrfjwc lmbtkhch srwg lvq bvrjztfm vwmb rpxwnbrw cmvjrf cdxsgqgs mtrfm wrzct + pznlvfk cgcdvbpt cnpqtw sfwsnkkw qjlmkkmv wrsctd lwdbkws qhvszv jzzpb jlgz ftdqspbf + vvsvkq znktlpx vcvccs kswfwbzv hwfbd grplms dfvt pmmd nvb tgjpq hgsx qgsvbgws gzrq + kmbgdwm tgmwmsc lsmphpk pwpznr mhcskk bmzqtdx pgwd jplzc cbkgf zbmclc tzhqvbt wkq + hljqwkz vgclcmdx ggzb vsng tjw ckxtmqx wffrgzp wbht rsqb gqwxpncw mkszj mhlrmd pcl + jqjgd rdrphff ftzkqg dgrhmgn zgl plkxf hzdb mmj plphnnv jvvc tlthnhrh ngkgnln nfv rtxct + ppsp rcfxhhh mbzkdw smdlrm cstjtb rhhmzvp tqbs szbmqd gbn fjmt fcppm qdgqls gxltm + mdrgqdht vxpbxrdj twxcfxk qzj wtfh vglkdghk xtdzrz rjldhzld mbd fgrfb hffjd hcr + vghjwkvl pfkjshg rrflt zflwbn xffjdlfs bbzvs wdxmfr fvntg twjhgcc zwvwrnn gcnzl ftfpd + wfqxrnzf mbccsd szltzjm kpbslq wxxchz szzh tgq jxnng cmrgdh pdxjxpxr bslbmwm mdkc + nqjflf vsrp gbprtv mkfsfcwd zkf pqsq chbb bmt smtkrxjx nfkltv cvhxd zwwx bzqcnzwp wcpn + jmqkbclx'''.split() + + txt_B = '''pwbfdmtc jms gswg wvsscb ffq lbrhbn lcxc hcr thc mghts vkgfc nrvfgs dsrdq + tcmfz scqskgsl twgzh whts dqt twtksl lcrdlc dpzrl hwlqvc xcfstz rfkvbr bzmvqp qxrs + jlmwtcs nmjkkmpg kbcbg shdf qxpm qbm hlcnqnw jwhvvrtr kccw njxtbh hbtn lqmxbx krnn hcv + ptqtwp xgnfggb bjdd nfgkxsw kgzcf bgncx rbsfrrcf vjwsjpw jbtcbqm xhhg kfpqcpx bfxlg + qddzdv rvfqp hphjhns xhk npdd gsxm ffkbj gwdxkhr ddqmr jnzznp jzsgkb lcgsgjvh xvsbdw + klzsxz xpjkjxc gth dtrmkn qzcsksd vsdrhj vtlxg kdtxsj sgs chnz bdllcsdl trggnlpd gwbvj + stnhs vqbhj tdhps sgkk mxnswm ghm sqhfcnlk lpwqpn gcgg mjxh prmqclss zfn gplktxj + vkjnkkv fzzx vdslwsdk fxt pnbqqbk ksfgcvw hxfq xxd rvqzhmm ctvfgxzv nrzdkx nsxmr + bnvkmhcl srvc nczkp zbgsxg nmpx vrqq xfmnsjc zszmrfjv cbwjfldn fgn mzpp crjnct cmh cwh + cvdk cslq tvr gggck pfs thfdcpxt fcffvg bwxr bstbzwsx ghhq ldzzlkg zmfkxvms lfn + zzzfchrk lktdlrlx wzjcvj nbbkqjt lthk wnxsmnx dzftkjr fqfqcjtd dzsvqbnx zhprp cqlphsk + cjvrwg fkhr mxrg tdbxnwrg sdcptlln tjsh vbmd vlgfskcx xtkdp ttjcc qtlmgsh kbndtscg nfw + kctx rcltszw hbjr zld npqqm bpcqrhq szzw vbxj ghhmdq nhfptrsg vpkgwcd rkkxqk jhxpngr + qnkfd wvcsmb bgnvwqln gfbrqn rjjp dvfqjqsf rspxz cvrjxjq gtps fbg rdp pbzqnc nssd + rrpzcwp drfrgjx wvcpw fst frp lmz gbb brzbhlns qsjgzzzp jwvbhl pchqk vhpbdwd mwtlm + wbdxk rsfpxl kqt psr bcdktps mrgnflhr fvxsmsbx rqprpvj clnr hdqzjc bndwhjwp fbbkvdhr + mlgtjw ntk pxv nsnv jnwp vtksnpbb lpwl rslljk hsd rzfmdp xlbnkbw ptfhnlc jjc dpptqzc + jgrt jgxn bgg hslbhksz lhld jfdjq mmttm hwjbnqwv dcxggwhc dcnhhltm fttbf xjnjhgh + tchctgjn fvjkmj wkfxqzkx knbhrwgs xmszj smnrwmlv cdbdwsjf grtkzrwh rwmbvt zssswpc cdvr + klhtb bhkwfwxm bdjzlg nnw hnw fkm dzxpk fmvx kwfj vbf bgp frfbhk kvqwc skddwrtg + brgkfqnf xmwth wrmv rzmjrbfb pkj hckr sfbvz vtfbq fmzf tkhnb srd slkbcmj ppq kxgdbxhh + grwpg hxhjznc ttmgnwb lljfz ftkgv fsjmrvcx dljps mtgnc bkwfwfnj npfvr qlgpv hmqhxfpb + vvwtkrf nfchzb phmhxkck ngrngr lvd dgbwpk txlttnpb ppldgl wsmngb xtxsblgt xxtctgsj + pbvtkm pmcmrmvf phcxvpf wtbfv mvclz dvsl tmzxrrg gbjz dtlsp klmjxg fxh svtlgdl vvlhntpt + zgtkjdm lbjrnmt fbbhqvg dwqnsgj bjjcsvms tlpzlxj bcw rtvmzn kjtqpxhw zkvkdxz dcx zqmsnl + rvqw kgsh gbwdh wslrbz pfnpqh mgj kgmq hpzmp kpr jgz bksx lvsbxzv qgzf qcgpc pvf xlt + znjntxpj stgwsc vxgcfc cbvwhf tbxwpk nbjbkrz rgc wps rjlfpch bxqhw nckdtf bsncq + cnsmqxwn mzmlgpp vnxr qgjs vpkpbsn tgmw lbcxxgsf nnmr wbpdssgm nmddl zcbpcbpt twrkx + sdqxsnw lntr rzv hgjjksxf qpnnjwl hbcv fkwkbd ncv plr lmpfkk dpcj jzjbjgp bdttl + wrrdnmjz mxqxqdxc shztl gdzj rntpnh rjrlrfk rncp qlrhnww rdzhzx qnnxhm gtd lqklxr + gpgpqtrc hfhp hxl bnr fpvxzwmx pfrxglb xmchrvwx wbnxl vjxgbs vddhjkq wndwxs mqndvm + hvbncjw pbmlw hzjwqn nfgxqmb pfvnpwj xbwknvmr xtm cnxck qnmtrvx kmhj hdfrtd gqz srlml + ckx pwlhnpgf rkln tvq vjgrlfs vpvwnjtg wbswcvbh dzcjppjm slt zvxhgq xhcvvc rjd xhqdvhmp + nqlnsk hxmjpmnv sjwwc hbjvpw dpmdnz sxpb qznnxl nwnlmbx vdb hgkkwd znsxfqs kqwjtrcg + vhbnd rpgtkzz fmt nmzhrrqn qbqbvpsm kqwxr gvp xvrvsdf pxwt vkdns dpf jwnwz mxpwc xdvs + drrlpnr xvpztf pxzm jtg fvfgnzx qndpq dmzwnfgm jzknzgk clbpzcpd xhxsqp zbfck btzjd jwbt + gwtll kqj wlsdx sdvnw mqpvxk kjdkt frgwz mpqnqr lpj gvc hcdp zpvrdnc ckvmtbvf bddvc + mptrq xrzwj lzlbc pvgkrhd wlkdtjz pslzhzhc qmrr crkxcs jtxhfvr qzd fwrgdmjt cmg xvhcb + zmllbxs mxg plzxjqlk cwnf mqt hlsssh lvmptxcd zdbsvmll wshnn xzrz xsnhn jhg jtkqhh kcsb + bgsfnz mfxmqjn glzb qtwhllw nfkjfn xgw mvssxl hpb vjhlfgld cgfwq qdvjskx ntnhcl ckm + rqrsw dpff krrkl mcs xnk jpnx llw ljhqlbhs njdm gph nwmm bcclbzz wjfktwv mgthn kltqfx + hqntlps bdr dqtswd vqmkgkb pmznqzh mwgf nndtsx xfrmgqqj mvkfdhh qxp pvpcmx mhnhb slw + clvtxn nfpnlr tsssrk rnvdjpc ptkp hrwx zgblvhlj lqrdrz bhtlqhvv mlpkx jsl vlj kbmfjgs + ktzb wrnn ztbcph lxccgcxh bkrhjtsl cbmhp hwswwqg rnwqq srhnz fkvl kcnr qbxwpg hnss gjdn + rnxhwgd jgngwzc kfvg nwkjt rhjtsvv txk szkpmn nnzbqwgs pjjzqkvx bkw dfcbw rffn qph + kckksgp nzn tpqnm znzppsg tvcgnrb zgdsp tqlqrf vjqqxsp pwj pgft cvl cvr cnhgxsd lkd qlw + vwtbh mfxs gbgw'''.split() + + + .. tab:: Ejercicio 2 + + Estos pergaminos están en el antiguo y misterioso idioma Googlon. Después de muchos años de estudio, + los lingüistas ya conocen algunas características de este idioma. + Primero, las letras de Googlon se clasifican en dos grupos: las letras **z, m, b** se denominan + "letras de tipo zombi", mientras que las demás se conocen como "letras de tipo sobrevivientes". + Los lingüistas han descubierto que las preposiciones en Googlon son palabras que comienzan con una + letra de tipo zombi y terminan con otra letra, es fácil ver que hay 71 preposiciones en el Texto A. + + .. activecode:: ac_r02_2 + :nocodelens: + :include: ac_r02_1 + + **Calcule cuántas preposiciones existen en el texto B.** El resultado asígnelo a la variable + ``prep_B``. **Nota**: ``txt_A`` y ``txt_B`` ya están definidas aunque no aparezcan en la ventana + de código siguiente. + + ~~~~ + zombi = "zmb" + prep_B = 0 + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(prep_B, 76, "Esperado: Probando que prep_B tenga el valor correcto") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + Otro hecho interesante descubierto por los lingüistas es que, en Googlon, los verbos son siempre + palabras de 7 letras que terminan en una letra de tipo sobreviviente. Además, si un verbo comienza con + una letra de tipo sobreviviente, el verbo está en primera persona. Así, leyendo el Texto A, es posible + identificar 84 verbos en el texto, de los cuales 70 están en primera persona. + + .. activecode:: ac_r02_3 + :nocodelens: + :include: ac_r02_1, ac_r02_2 + + Calcule cuántos son los verbos en el Texto B, y asigne ese valor a la variable ``verbos_B``. Después + calcule cuántos de esos verbos están en primera persona, y asigne ese valor a la variable ``persona_1_B``. + **Recuerde**: los textos ya están definidos, al igual que la variable ``zombi`` del código anterior. + + ~~~~ + verbos_B = 0 + persona_1_B = 0 + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(verbos_B, 86, "Esperado: Probando que verbos_B tenga el valor correcto") + self.assertEqual(persona_1_B, 76, "Esperado: Probando que persona_1_B tenga el valor correcto") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + Un profesor universitario utilizará los textos A y B para enseñar Googlon a los estudiantes. + Para ayudar a los alumnos a comprender el texto, este profesor necesita crear una lista de + vocabulario para cada texto, es decir, una lista ordenada de las palabras que aparecen en cada + uno de los textos. Estas listas deben ordenarse. En Googlon, como en nuestro alfabeto, las + palabras están ordenadas lexicográficamente, pero el problema es que en Googlon, el orden de + las letras en el alfabeto es diferente al nuestro. Su orden es: zmbtshjpnwlrcxkqvdgf. + Por lo tanto, al hacer estas listas, el profesor debe respetar el orden alfabético de Googlon. + + .. activecode:: ac_r02_4 + :nocodelens: + :include: ac_r02_1 + + El profesor preparó la lista de vocabulario (ordenada) para el Texto A; obsérvela en la variable + ``lista_A``. ¿Cuál sería la lista de vocabulario ordenada del Texto B? Haga un programa que realice + esta lista, y la guarde en la variable ``lista_B``. **Recuerde**: los textos ya están definidos como + en el primer ejercicio (Ejercicio 1). + + ~~~~ + orden = "zmbtshjpnwlrcxkqvdgf" + + lista_A = ['zzrr', 'zmnc', 'zbmclc', 'zbrpktxj', 'zbdbsq', 'ztm', 'ztvkmv', 'zhzvm', 'zjcrkzm', 'zjqcbxf', 'znngdwb', 'znktlpx', 'zndtfmf', 'zwwx', 'zwwdsd', + 'zwvwrnn', 'zlmtqs', 'zldk', 'zcjjttpt', 'zxljnd', 'zkf', 'zqwb', 'zvtnbs', 'zdrfjwc', 'zgnlpgwl', 'zgl', 'zgqxqpvm', 'zflwbn', 'mmj', 'mmksm', 'mbzkdw', 'mbccsd', 'mbd', 'mtrfm', 'mhj', 'mhlrmd', 'mhcskk', 'mjhskxjh', 'mjwrncd', 'mpqxtbzb', 'mlsm', 'mlfmddsn', 'mrddntg', 'mclvp', 'mcld', 'mxjccgv', 'mxqhpg', 'mkmnwtzv', 'mkt', 'mkszj', 'mkfsfcwd', 'mqdgvskt', 'mqfsrwt', 'mdz', 'mdrgqdht', 'mdcqlbwx', 'mdxlzvkg', 'mdkc', 'mdvcfqkt', 'mfm', + 'mfhllb', 'bzrznlh', 'bzccxd', 'bzqcnzwp', 'bzfqkpjj', 'bmzqtdx', 'bmt', 'bbzvs', 'bbdqpvn', 'bsb', 'bslbmwm', 'bhrfvh', 'bjgllxv', 'bpngkf', 'bplzzpjw', 'bwfgzmjn', 'blnw', 'blx', 'brzxg', 'brprszrc', 'brxk', 'bkjcm', 'bvrjztfm', 'bdjxr', 'bdnfbh', 'bghqpnl', 'bfjmw', 'bfjbs', 'tzhqvbt', 'tzwvbkfq', 'tzqcvz', 'tzd', 'tmjlqw', 'tbw', 'ttjtx', 'ttl', 'tsmrhhtm', 'tjpdp', 'tjw', 'tjgmjzh', 'tpppxf', 'tplwbr', 'tpvdrlf', 'tnbqgv', 'tnt', 'twjhgcc', 'twxcfxk', 'tlthnhrh', 'trzz', 'trxl', 'trvpx', 'txz', 'tkljpkfc', 'tqbs', 'tvphkg', 'tvpjwzb', 'tdbsgf', 'tdsbdhv', 'tdjzcwj', 'tgmwmsc', 'tgtclv', 'tgsffh', 'tgjpq', 'tgnq', 'tgq', 'szzh', 'szbmqd', 'szltzjm', 'smtkrxjx', 'smdlrm', 'sbst', 'sbnfjs', 'sbrkdjmh', 'spzzbc', 'swff', 'srtfttv', 'srwg', 'sxcdqtlt', 'skhcwxw', 'skwkh', 'sklfrc', 'skxpc', 'skkfq', 'svztn', 'sfwsnkkw', 'hzrv', 'hzdb', 'hmnf', 'hbtjpvm', 'hbff', 'htldnxcn', 'htkmdbx', 'hsc', 'hhrrx', 'hhcxnnhn', 'hphvdvl', 'hwfbd', 'hljqwkz', 'hlnls', 'hlxx', 'hlkxtc', 'hrdqrds', 'hcr', 'hxr', 'hqlgx', 'hdslhv', 'hdj', 'hgsx', 'hffjd', 'jzzpb', 'jzrr', 'jzdfqq', 'jmstqwx', 'jmqkbclx', 'jbmlsfkx', 'jbnplx', 'jbnw', 'jbw', 'jbvqmb', 'jtmdmt', 'jtwhxdx', 'jsfpllns', 'jsfkd', 'jhztz', 'jhtxc', 'jjqn', 'jplzc', 'jntktdz', 'jlhpgh', 'jlgz', 'jcw', 'jxsd', 'jxnng', 'jkk', 'jqbcddqh', 'jqjgd', 'jvcmkbxv', 'jvkwr', 'jvvc', 'jgw', 'jgl', 'jfmcl', 'jfhhv', 'jfxzx', 'pznlvfk', 'pmmd', 'pmnt', 'pmgtzlng', 'pbmp', 'ptmzl', 'ptmnzqkg', 'ptg', 'psjc', 'phbq', 'phn', 'phk', 'pjcjzct', 'ppzpvfbv', 'ppsp', 'pphslgf', 'pnhc', 'pwpznr', 'pljpvcn', 'plphnnv', 'plkxf', 'pctgq', 'pcl', 'pcvpwjb', 'pxcpvkmm', 'pkqxrsw', 'pqsq', 'pqc', 'pvf', 'pdhqn', 'pdnqm', 'pdxjxpxr', 'pdfqlsv', 'pgbkhc', 'pgjjhr', 'pgwd', 'pfcpt', 'pfcgz', 'pfkjshg', 'nmmqnzfn', 'nmc', 'nmdzgmnr', 'nbkvsrf', 'nsx', 'njq', 'njqw', 'njv', 'njfqrzxj', 'nwjjkrdq', 'nlbcwrvv', 'nlvgr', 'nrpzqfr', 'ncrmzr', 'nkjk', 'nqbh', 'nqjflf', 'nvmfhshh', 'nvb', 'ndtbsqsh', 'ngsbphqb', 'ngwrbrfk', 'ngc', 'ngkgnln', 'ngqzs', 'nfhvn', 'nfkltv', 'nfv', 'wzb', 'wzg', 'wzfsf', 'wmvjxdsw', 'wbht', 'wbcjprr', 'wtsp', 'wthwv', 'wtlsx', 'wtfh', 'whshcrk', 'whnjkv', 'wjg', 'wptc', 'wpfl', 'wnlmw', 'wwmngbk', 'wlsxsvf', 'wlj', 'wrzct', 'wrsctd', 'wrgf', 'wcjlrs', 'wcptgbc', 'wcpn', 'wcc', 'wxxchz', 'wknwbcq', 'wkq', 'wdc', 'wdxmfr', 'wfqxrnzf', 'wffrgzp', 'lzhr', 'lzq', 'lzgfnkmg', 'lmbtkhch', 'lmbjjx', 'lmbfvsv', 'lmknq', 'lmq', 'lbbkssx', 'lbrnrsf', 'lbkw', 'lbqjrp', 'ltjwn', 'ltqxkt', 'lsmphpk', 'ljxh', 'ljdz', 'lphf', 'lnt', 'lnkfqjt', 'lwlqdh', 'lwdbkws', 'llshm', 'lljs', 'lllkssb', 'lrljqdct', 'lxzscps', 'lxtf', 'lxkmnzx', 'lqmtsnrn', 'lqncvrh', 'lqg', 'lvwht', 'lvq', 'lvqckrl', 'lgh', 'lgf', 'lfhkmb', 'lfjvrhr', 'rzp', 'rmmhtmbp', 'rbr', 'rtm', 'rtb', 'rtxct', 'rskfms', 'rsqb', 'rsd', 'rhhmzvp', 'rjldhzld', 'rpxwnbrw', 'rwtzbhs', 'rwtxljp', 'rwjls', 'rrflt', 'rcfxhhh', 'rxrmqp', 'rkzlhbnx', 'rkvg', 'rqm', 'rqkr', 'rdrphff', 'rgtrj', 'rgpgqz', 'rflzw', 'rfqsr', 'rfqdh', 'czhhtclr', + 'cmsqdjx', 'cmrgdh', 'cmvjrf', 'cmgp', 'cbk', 'cbkgf', 'cstjtb', 'chbb', 'chv', 'cpcnpnww', 'cnpqtw', 'cncdbm', 'cwmb', 'cwkc', 'cltdd', 'crbhzfs', + 'ccx', 'cxpplqbq', 'ckxtmqx', 'cqw', 'cvhxd', 'cdswmbgb', 'cdxsgqgs', 'cgp', 'cgpn', 'cgrtr', 'cgcdvbpt', 'xmtzz', 'xblfrb', 'xtdzrz', 'xhjk', 'xpbddsjw', 'xwxjhbc', 'xlc', 'xldsnqds', 'xrsrjv', 'xrqhp', 'xxzdlwzx', 'xxtlt', 'xxcfpp', 'xqbs', 'xvqnd', 'xvgkv', 'xdlsm', 'xgj', 'xggzgkln', 'xftg', 'xfpj', 'xffjdlfs', 'kzzsbq', 'kztrcqxt', 'kmbgdwm', 'kmk', 'kbg', 'ktbcx', 'kszjq', 'ksptr', 'kswfwbzv', 'kslnx', 'khzzw', 'khhmfng', 'khlbtg', 'khqr', 'kpmmgxb', 'kpbslq', 'knhmmtks', 'knlwvk', 'kwhcrd', 'kwchwcv', 'kwvnrfm', 'krh', 'krprtxf', 'krdb', 'kcr', 'kcxl', 'kcdwcpdm', 'kknhkq', 'kkrr', 'kqzrlxz', 'kvtgzpl', 'kgzsb', 'kgj', 'qzz', 'qzj', 'qmwknt', 'qbpsv', 'qbvvz', 'qslm', 'qsfctn', 'qhvszv', 'qjlmkkmv', 'qjvg', 'qnghqcch', 'qwl', 'qlmhxrrf', 'qlpt', 'qcrx', 'qcxr', 'qkkjgg', 'qdht', 'qdr', 'qddg', 'qdgqls', 'qgsvbgws', 'qfbrdg', 'vmhp', 'vmpdxkv', 'vmqzmg', 'vmd', 'vttn', + 'vth', 'vsng', 'vsrp', 'vhxdj', 'vjmmf', 'vjq', 'vwmb', 'vwddsdl', 'vcj', 'vcvccs', 'vxpbxrdj', 'vxf', 'vkvqhk', 'vkffrqvt', 'vqbq', 'vqdmjdsb', 'vvsvkq', 'vdbbxdtw', 'vdszkb', 'vghjwkvl', 'vglkdghk', 'vgclcmdx', 'vfb', 'vftnnd', 'dmp', 'dtblv', 'dtrsfb', 'dsgnhsf', 'djbgqqk', 'djsv', 'djftp', 'dpl', 'dwsk', 'dwlrgxtm', 'dlbnhz', 'dcsbhwp', 'dcrzslrf', 'dcxsrkl', 'dckqls', 'dcgxxcqm', 'dxz', 'dxmkk', 'dxss', 'dxpx', 'dkzxctcn', 'dknttlb', 'dqfjwtv', 'dvmj', 'dgsxl', 'dgwd', 'dgrhmgn', 'dggshkxz', 'dfbnht', 'dfj', 'dfctpgr', 'dfvt', 'gzrq', 'gmv', 'gbprtv', 'gbn', 'gthkq', 'gtrpzhwb', 'gtvrwp', 'gsrxcb', 'gscvghmj', 'gsqfgjn', 'ghfntj', 'gjbbg', 'gjw', 'gjvnj', 'gpn', 'gnksf', 'gwpcph', 'grplms', 'gcmdfzdx', 'gcnzl', 'gcnkszfk', 'gxltm', 'gxglr', 'gkt', 'gkh', 'gkhp', 'gqhdfchv', 'gqjjcbjw', 'gqwxpncw', 'gvbfxtbv', 'gvhkcsvw', 'gvwg', 'ggzb', 'ggvf', 'ggd', 'gfc', 'fzlxll', 'ftzkqg', 'ftdqspbf', 'ftfpd', 'fshm', 'fsp', 'fjmt', 'fpbwbzb', 'fpj', 'fwwm', 'fwqwfxs', 'frtvg', 'frs', 'frskk', 'frp', 'fcppm', 'fkzql', 'fkmrtn', 'fqppvgk', 'fvjdqd', 'fvntg', 'fdsfsc', 'fdh', 'fgmcd', 'fgrfb', 'fgvsxzp'] + + # Comience aquí su programa + lista_B = [] + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + B = ['zzzfchrk', 'zmllbxs', 'zmfkxvms', 'zbgsxg', 'zbfck', 'ztbcph', 'zszmrfjv', 'zssswpc', 'zhprp', 'zpvrdnc', 'znzppsg', 'znsxfqs', 'znjntxpj', 'zld', 'zcbpcbpt', 'zkvkdxz', 'zqmsnl', 'zvxhgq', 'zdbsvmll', 'zgblvhlj', 'zgtkjdm', 'zgdsp', 'zfn', 'mzmlgpp', 'mzpp', 'mmttm', 'mtgnc', 'mhnhb', 'mjxh', 'mptrq', 'mpqnqr', 'mwtlm', 'mwgf', 'mlpkx', 'mlgtjw', 'mrgnflhr', 'mcs', 'mxpwc', 'mxnswm', 'mxrg', 'mxqxqdxc', 'mxg', 'mqt', 'mqpvxk', 'mqndvm', + 'mvssxl', 'mvclz', 'mvkfdhh', 'mgthn', 'mghts', 'mgj', 'mfxmqjn', 'mfxs', 'bzmvqp', 'btzjd', 'bstbzwsx', 'bsncq', 'bhtlqhvv', 'bhkwfwxm', 'bjjcsvms', 'bjdd', 'bpcqrhq', 'bnr', 'bnvkmhcl', 'bndwhjwp', 'bwxr', 'brzbhlns', 'brgkfqnf', 'bcw', 'bcclbzz', 'bcdktps', 'bxqhw', 'bksx', 'bkw', 'bkwfwfnj', 'bkrhjtsl', 'bdttl', 'bdjzlg', 'bdllcsdl', 'bdr', 'bddvc', 'bgsfnz', 'bgp', 'bgncx', 'bgnvwqln', 'bgg', 'bfxlg', 'tmzxrrg', 'tbxwpk', 'ttmgnwb', 'ttjcc', 'tsssrk', 'thc', 'thfdcpxt', 'tjsh', 'tpqnm', 'twtksl', 'twrkx', 'twgzh', 'tlpzlxj', 'trggnlpd', 'tcmfz', 'tchctgjn', 'txlttnpb', 'txk', 'tkhnb', 'tqlqrf', 'tvr', 'tvcgnrb', 'tvq', 'tdbxnwrg', 'tdhps', 'tgmw', 'szzw', 'szkpmn', 'smnrwmlv', 'stnhs', 'stgwsc', 'shztl', 'shdf', 'sjwwc', 'slt', 'slw', 'slkbcmj', 'srhnz', 'srlml', 'srvc', 'srd', 'scqskgsl', 'sxpb', 'skddwrtg', 'sqhfcnlk', 'svtlgdl', 'sdcptlln', 'sdqxsnw', 'sdvnw', 'sgs', + 'sgkk', 'sfbvz', 'hzjwqn', 'hmqhxfpb', 'hbtn', 'hbjr', 'hbjvpw', 'hbcv', 'hslbhksz', 'hsd', 'hpzmp', 'hpb', 'hphjhns', 'hnss', 'hnw', 'hwswwqg', 'hwjbnqwv', 'hwlqvc', 'hlsssh', 'hlcnqnw', 'hrwx', 'hcr', 'hckr', 'hcv', 'hcdp', 'hxmjpmnv', 'hxhjznc', 'hxl', 'hxfq', 'hqntlps', 'hvbncjw', 'hdqzjc', + 'hdfrtd', 'hgjjksxf', 'hgkkwd', 'hfhp', 'jzsgkb', 'jzjbjgp', 'jzknzgk', 'jms', 'jbtcbqm', 'jtxhfvr', 'jtkqhh', 'jtg', 'jsl', 'jhxpngr', 'jhg', 'jjc', 'jpnx', 'jnzznp', 'jnwp', 'jwbt', 'jwhvvrtr', 'jwnwz', 'jwvbhl', 'jlmwtcs', 'jgz', 'jgngwzc', 'jgrt', 'jgxn', 'jfdjq', 'pmznqzh', 'pmcmrmvf', 'pbzqnc', 'pbmlw', 'pbvtkm', 'ptkp', 'ptqtwp', 'ptfhnlc', 'pslzhzhc', 'psr', 'phmhxkck', 'phcxvpf', 'pjjzqkvx', 'ppldgl', 'ppq', 'pnbqqbk', 'pwbfdmtc', + 'pwj', 'pwlhnpgf', 'plzxjqlk', 'plr', 'prmqclss', 'pchqk', 'pxzm', 'pxwt', 'pxv', 'pkj', 'pvpcmx', 'pvgkrhd', 'pvf', 'pgft', 'pfs', 'pfnpqh', 'pfrxglb', 'pfvnpwj', 'nzn', 'nmzhrrqn', 'nmjkkmpg', 'nmpx', 'nmddl', 'nbbkqjt', 'nbjbkrz', 'ntnhcl', 'ntk', 'nssd', 'nsnv', 'nsxmr', 'nhfptrsg', 'njxtbh', 'njdm', 'npqqm', 'npdd', 'npfvr', 'nnzbqwgs', 'nnmr', 'nnw', 'nndtsx', 'nwmm', 'nwnlmbx', 'nwkjt', 'nrzdkx', 'nrvfgs', 'nczkp', 'nckdtf', 'ncv', 'nqlnsk', 'ngrngr', 'nfpnlr', 'nfw', 'nfchzb', 'nfkjfn', 'nfgxqmb', 'nfgkxsw', 'wzjcvj', 'wbswcvbh', 'wbpdssgm', 'wbnxl', 'wbdxk', 'wtbfv', 'wsmngb', 'wshnn', 'wslrbz', 'whts', 'wjfktwv', 'wps', 'wnxsmnx', 'wndwxs', 'wlsdx', 'wlkdtjz', 'wrmv', 'wrnn', 'wrrdnmjz', 'wkfxqzkx', 'wvsscb', 'wvcsmb', 'wvcpw', 'lzlbc', 'lmz', 'lmpfkk', 'lbjrnmt', 'lbrhbn', 'lbcxxgsf', 'lthk', 'lhld', 'ljhqlbhs', 'lpj', 'lpwl', 'lpwqpn', 'lntr', 'lljfz', 'llw', 'lcrdlc', 'lcxc', 'lcgsgjvh', 'lxccgcxh', 'lktdlrlx', 'lkd', 'lqmxbx', 'lqrdrz', 'lqklxr', 'lvmptxcd', 'lvsbxzv', 'lvd', 'ldzzlkg', 'lfn', 'rzmjrbfb', 'rzv', 'rzfmdp', 'rbsfrrcf', 'rtvmzn', 'rspxz', 'rslljk', 'rsfpxl', 'rhjtsvv', 'rjjp', 'rjlfpch', 'rjrlrfk', 'rjd', 'rpgtkzz', 'rntpnh', 'rnwqq', 'rncp', 'rnxhwgd', 'rnvdjpc', 'rwmbvt', 'rrpzcwp', 'rcltszw', 'rkln', 'rkkxqk', 'rqprpvj', 'rqrsw', 'rvqzhmm', 'rvqw', 'rvfqp', 'rdzhzx', 'rdp', 'rgc', 'rfkvbr', 'rffn', 'cmh', 'cmg', 'cbmhp', 'cbwjfldn', 'cbvwhf', 'ctvfgxzv', 'cslq', 'chnz', 'cjvrwg', 'cnsmqxwn', 'cnhgxsd', 'cnxck', 'cwh', 'cwnf', 'clbpzcpd', 'clnr', 'clvtxn', 'crjnct', 'crkxcs', 'ckm', 'ckx', 'ckvmtbvf', 'cqlphsk', 'cvl', 'cvr', 'cvrjxjq', 'cvdk', 'cdbdwsjf', 'cdvr', 'cgfwq', 'xzrz', 'xmszj', 'xmwth', 'xmchrvwx', 'xbwknvmr', 'xtm', 'xtxsblgt', 'xtkdp', 'xsnhn', 'xhhg', 'xhcvvc', 'xhxsqp', 'xhk', 'xhqdvhmp', 'xjnjhgh', 'xpjkjxc', 'xnk', 'xlbnkbw', 'xlt', 'xrzwj', 'xcfstz', 'xxtctgsj', 'xxd', 'xvsbdw', 'xvhcb', 'xvpztf', 'xvrvsdf', 'xdvs', 'xgnfggb', 'xgw', 'xfmnsjc', 'xfrmgqqj', 'kmhj', 'kbmfjgs', 'kbndtscg', 'kbcbg', 'ktzb', 'ksfgcvw', 'kjtqpxhw', 'kjdkt', 'kpr', 'knbhrwgs', 'kwfj', 'klzsxz', 'klmjxg', 'kltqfx', 'klhtb', 'krnn', 'krrkl', 'kctx', 'kcsb', 'kcnr', 'kccw', 'kckksgp', 'kxgdbxhh', 'kqt', 'kqj', 'kqwjtrcg', 'kqwxr', 'kvqwc', 'kdtxsj', 'kgzcf', 'kgmq', 'kgsh', 'kfpqcpx', 'kfvg', 'qznnxl', 'qzcsksd', 'qzd', 'qmrr', 'qbm', 'qbxwpg', 'qbqbvpsm', 'qtwhllw', 'qtlmgsh', 'qsjgzzzp', 'qph', 'qpnnjwl', 'qnmtrvx', 'qnnxhm', 'qnkfd', 'qndpq', 'qlw', 'qlrhnww', 'qlgpv', 'qcgpc', 'qxp', 'qxpm', 'qxrs', 'qdvjskx', 'qddzdv', 'qgzf', 'qgjs', 'vbmd', 'vbxj', 'vbf', 'vtlxg', 'vtksnpbb', 'vtfbq', 'vsdrhj', 'vhbnd', 'vhpbdwd', 'vjhlfgld', 'vjwsjpw', 'vjxgbs', 'vjqqxsp', 'vjgrlfs', 'vpkpbsn', 'vpkgwcd', 'vpvwnjtg', 'vnxr', 'vwtbh', 'vlj', 'vlgfskcx', 'vrqq', 'vxgcfc', 'vkjnkkv', 'vkdns', 'vkgfc', 'vqmkgkb', 'vqbhj', 'vvwtkrf', 'vvlhntpt', 'vdb', 'vdslwsdk', 'vddhjkq', 'dzsvqbnx', 'dzcjppjm', 'dzxpk', 'dzftkjr', 'dmzwnfgm', 'dtlsp', 'dtrmkn', 'dsrdq', 'dpzrl', 'dpmdnz', 'dpptqzc', 'dpcj', 'dpf', 'dpff', 'dwqnsgj', 'dljps', 'drrlpnr', 'drfrgjx', 'dcnhhltm', 'dcx', 'dcxggwhc', 'dqt', 'dqtswd', 'dvsl', 'dvfqjqsf', 'ddqmr', 'dgbwpk', 'dfcbw', 'gbb', 'gbjz', 'gbwdh', 'gbgw', 'gth', 'gtps', 'gtd', 'gswg', 'gsxm', 'ghm', 'ghhmdq', 'ghhq', 'gjdn', 'gph', 'gplktxj', 'gpgpqtrc', 'gwbvj', 'gwtll', 'gwdxkhr', 'glzb', 'grtkzrwh', 'grwpg', 'gcgg', 'gqz', 'gvp', 'gvc', 'gdzj', 'gggck', 'gfbrqn', 'fzzx', 'fmzf', 'fmt', 'fmvx', 'fbbhqvg', 'fbbkvdhr', 'fbg', 'fttbf', 'ftkgv', 'fst', 'fsjmrvcx', 'fpvxzwmx', 'fwrgdmjt', 'frp', 'frgwz', 'frfbhk', 'fcffvg', 'fxt', 'fxh', 'fkm', 'fkhr', 'fkwkbd', 'fkvl', 'fqfqcjtd', 'fvjkmj', 'fvxsmsbx', 'fvfgnzx', 'fgn', 'ffkbj', 'ffq'] + self.assertEqual(lista_B, B, "Probando que lista_B tenga el valor correcto") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + Pero, ¿cómo escriben los Googlons los números? Bueno, en Googlon, las palabras también son + números dados en base 20, donde cada letra es un dígito. En Googlon, la primera posición es + la unidad y corresponde a la letra de hasta la izquierda de la palabra, la segunda posición + tiene un valor de 20, la tercera de 400 y así sucesivamente. + Los valores de las letras se dan en el orden en que aparecen en el alfabeto Googlon (que es + diferente de nuestro orden, como vimos anteriormente). Es decir, la primera letra del alfabeto + Googlon, que es la z, representa el dígito 0, la segunda representa el dígito 1, y así sucesivamente. + + Por ejemplo, la palabra ``zmbzmb`` tiene un valor numérico de ``6560820``. La explicación es la siguiente: + En el albafeto Googlon, las letras ``z`` ``m`` y ``b`` son las tres primeras. Si representamos esa + palabra en dígitos según las reglas anteriores, éste sería su valor: ``012012``. Como último paso hace falta + convertirlo a base 20. Según las reglas anteriores, la conversión se hace de la siguiente forma: + :math:`(0 * 1) + (1 * 20) + (2 * 20^2) + (0 * 20^3) + (1 * 20^4) + (2 * 20^5) = 6560820` + + .. activecode:: ac_r02_5 + :nocodelens + :include: ac_r02_1, ac_r02_4 + + Los Googlons consideran un número mágico (muy raro) si satisface una propiedad: el valor numérico + es divisible por 42 (respuesta para todo) y todos los dígitos son distintos entre sí. Al considerar + el Texto A como una lista de números (es decir, interpretar cada palabra como un número usando la + convención explicada anteriormente), notamos que hay 8 números mágicos: + **kpbslq, gtrpzhwb, ghfntj, ljdz, gthkq, lbqjrp, jplzc** y **gjw**. + + Y en el Texto B, ¿cuántos números mágicos hay y cuáles son? Guarde en la variable ``num_magicos`` + la cantidad de números mágicos que hay en el Texto B, y en la variable ``magia`` guarde cuales son. + **Recuerde**: Los textos ya están definidos, al igual que la variable ``orden`` del ejercicio anterior. + + ~~~~ + def base_20(num): + """Esta función convierte una palabra a su valor numérico""" + p20 = 1 + n = 0 + for c in num: + n += orden.find(c) * p20 + p20 *= 20 + return n + + num_magicos = 0 + magia = [] + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(num_magicos, 6, "Probando que num_magicos tenga el valor correcto") + self.assertEqual( + magia, + ["vbxj", "jnwp", "cdvr", "bksx", "jtg", "gjdn"], + "Probando que magia tenga el valor correcto", + ) + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/challenges/Reto03.rst.txt b/293/_sources/challenges/Reto03.rst.txt new file mode 100644 index 0000000000..cc5d37c793 --- /dev/null +++ b/293/_sources/challenges/Reto03.rst.txt @@ -0,0 +1,235 @@ +================================ +Reto Pygame -Tirador de zombies +================================ + +.. raw:: html + + + + + + +.. activecode:: ac_r03_1 + :language: python3 + :python3_interpreter: brython + + from browser import load, timer, window + load('../_static/game.js') + load('../_static/pygame.brython.js') + gjs = window.gamejs + gjs.image.preload(["../_static/zomb.png", "../_static/bg2.jpg", '../_static/human.png', '../_static/BlueBar1.jpg',\ + '../_static/bullet.png', '../_static/blast.png', "../_static/bg1.jpg"]) + gjs.ready() + + ^^^^ + import pygame + from pygame.color import * + from pygame.locals import * + import random + import math + + timer1=None + + class Chaser: + def __init__(self): + + self.running=True + #----shooter----< + self.shooterX = 235 + self.shooterY = 500 + self.shooterX1 = 0 + self.shooterY1 = 0 + #----Enemy-------< + self.enemyImg = [] + self.enemyX = [] + self.enemyY = [] + self.enemyX1 = [] + self.enemyY1 = [] + self.enemyBullet = [] + self.enemyBulY=0 + self.bulY1=[] + self.enemybulX=0 + #---bullet----< + self.bulletY = 500 + self.bulletX = 0 + self.bulletX1 = 0 + self.bulletY1 = 30 + self.bulletState = 'Ready' + #-----score----< + self.score_value=0 + self.j=0 + + + def score(self, scr): + font=pygame.font.SysFont('timesnewroman',30) + score=font.render('Score: '+ str(self.score_value),True, Color(255,255,255),Color(200,100,100)) + scr.blit(score,(10,10)) + + + def shooter(self, x, y, scr): + if x <= 0: + x = 0 + elif x >= 500: + x = 500 + elif y <= 400: + y=400 + elif y >= 550: + y=550 + scr.blit(pygame.image.load('../_static/human.png'), (x, y)) + + def enemy(self): + for i in range(8): + self.enemyImg.append(pygame.image.load('../_static/zomb.png')) + self.enemyX.append(random.randint(0, 500)) + self.enemyY.append(random.randint(5, 60)) + self.enemyX1.append(10) + self.enemyY1.append(40) + self.bulY1.append(2) + self.enemyBullet.append(pygame.image.load('../_static/BlueBar1.jpg')) + + def bullet(self, x, y, scr): + self.bulletState='fire' + scr.blit(pygame.image.load('../_static/bullet.png'), (x+8, y)) + + def collision_e_b(self, X, Y, i): + dist=math.sqrt((self.enemyX[i]-X)**2+(self.enemyY[i]-Y)**2) + if dist <=30: return True + else: return False + + def collision_E_S(self, x, y, i): + dist = math.sqrt((x-self.enemyX[i])**2+(y-self.enemyY[i])**2) + if dist <= 35: return True + else: return False + + def collision_enemyBul_S(self,enemybulX,enemyBulY,shooterX,shooterY): + dist=math.sqrt((enemybulX-shooterX)**2+(enemyBulY-shooterY)**2) + if dist <=24 : + scr.blit(pygame.image.load('../_static/blast.png'),(self.shooterX,self.shooterY)) + return True + else: return False + + + def over(): + scr.blit(pygame.image.load('../_static/bg2.jpg'),(0,0)) + scr.blit(game,(50,int(600/2))) + pygame.display.update() + + def over_helper(): + global timer1 + timer.clear_interval(timer1) + timer1 = None + over() + + + + scr = pygame.display.set_mode((550, 600)) + font=pygame.font.SysFont('timesnewroman',30) + game=font.render('Game Over -\n Press run to Play Again',True, Color(230,220,170)) + p1= Chaser() + p1.enemy() + p1.enemybulX=p1.enemyX[random.randint(0,7)] + + + def func(): + scr.blit(pygame.image.load('../_static/bg2.jpg'),(0,0)) + scr.blit(pygame.image.load('../_static/BlueBar1.jpg'),(p1.enemybulX+15,p1.enemyBulY+12)) + p1.enemyBulY+=24 + + if p1.enemyBulY>=600: + p1.enemyBulY=p1.enemyY[random.randint(0,7)] + p1.enemybulX=p1.enemyX[random.randint(0,7)] + + for event in pygame.event.get(): + #---Shooter Movement------< + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_LEFT: + p1.shooterX1 -= 15 + if event.key == pygame.K_RIGHT: + p1.shooterX1 += 15 + if event.key == pygame.K_UP: + p1.shooterY1-=15 + if event.key == pygame.K_DOWN: + p1.shooterY1+=15 + if event.key == pygame.K_SPACE: + if p1.bulletState == 'Ready': + p1.bulletX = p1.shooterX + p1.bulletY = p1.shooterY + p1.bullet(p1.bulletX, p1.bulletY, scr) + if event.type == pygame.KEYUP: + p1.shooterX1 = 0 + p1.shooterY1 = 0 + p1.shooterX += p1.shooterX1 + p1.shooterY += p1.shooterY1 + p1.shooter(p1.shooterX, p1.shooterY, scr) + + # ------Enemy-----< + for i in range(8): + p1.enemyX[i] += p1.enemyX1[i] + if p1.enemyX[i] <= 0: + p1.enemyX1[i] = 14 + p1.enemyY[i] += p1.enemyY1[i] + elif p1.enemyX[i] >= 500: + p1.enemyX1[i] =- 14 + p1.enemyY[i] += p1.enemyY1[i] + scr.blit(p1.enemyImg[i], (p1.enemyX[i], p1.enemyY[i])) + + #-------collision of bullet and enemy--------< + col = p1.collision_e_b(p1.bulletX, p1.bulletY, i) + if p1.bulletState == 'fire': + if col: + scr.blit(pygame.image.load('../_static/blast.png'),(p1.bulletX,p1.bulletY)) + p1.score_value += 1 + p1.bulletY = 500 + p1.bulletState='Ready' + p1.enemyX[i] = random.randint(0,500) + p1.enemyY[i] = random.randint(5,60) + + #-------collision of Shooter and enemy--------< + col2 = p1.collision_E_S(p1.shooterX, p1.shooterY, i) + if col2: + # scr.blit(pygame.image.load('Icons\\bgover.png'),(550,600)) + scr.blit(pygame.image.load('../_static/blast.png'),(p1.shooterX,p1.shooterY)) + over_helper() + + + + + #------Collision of Bottom and Enemy--------< + if p1.enemyY[i] >= 600: + p1.enemyX[i] = random.randint(0,500) + p1.enemyY[i] = random.randint(5,60) + + #-------Collision of EnemyBul and Shooter-------< + col3= p1.collision_enemyBul_S(p1.enemybulX,p1.enemyBulY,p1.shooterX,p1.shooterY) + if col3: + scr.blit(pygame.image.load('../_static/bg2.jpg'),(550,600)) + scr.blit(pygame.image.load('../_static/blast.png'),(p1.shooterX,p1.shooterY)) + over_helper() + # break + + #--------Shooter Bullet------< + if p1.bulletY <= 0: + p1.bulletY = 480 + p1.bulletState = 'Ready' + if p1.bulletState == 'fire': + p1.bullet(p1.bulletX, p1.bulletY, scr) + p1.bulletY -= p1.bulletY1 + + p1.score(scr) + p1.j+=1 + pygame.display.update() + + + + pygame.init() + + timer1 = timer.set_interval(func,80) + + + + + diff --git a/293/_sources/challenges/Reto03_en.rst.txt b/293/_sources/challenges/Reto03_en.rst.txt new file mode 100644 index 0000000000..8ac46be903 --- /dev/null +++ b/293/_sources/challenges/Reto03_en.rst.txt @@ -0,0 +1,245 @@ +================================= +Pygame Challenge - Zombie Shooter +================================= + +.. raw:: html + + + + + + +.. activecode:: ac_r03_1_en + :language: python3 + :python3_interpreter: brython + + from browser import load, timer, window + load('../_static/game.js') + load('../_static/pygame.brython.js') + gjs = window.gamejs + gjs.image.preload(["../_static/zomb.png", "../_static/bg2.jpg", '../_static/human.png', '../_static/BlueBar1.jpg',\ + '../_static/bullet.png', '../_static/blast.png', "../_static/bg1.jpg"]) + gjs.ready() + + ^^^^ + import pygame + from pygame.color import * + from pygame.locals import * + import random + import math + + timer1=None + + class Chaser: + def __init__(self): + + self.running=True + #----shooter----< + self.shooterX = 235 + self.shooterY = 500 + self.shooterX1 = 0 + self.shooterY1 = 0 + #----Enemy-------< + self.enemyImg = [] + self.enemyX = [] + self.enemyY = [] + self.enemyX1 = [] + self.enemyY1 = [] + self.enemyBullet = [] + self.enemyBulY=0 + self.bulY1=[] + self.enemybulX=0 + #---bullet----< + self.bulletY = 500 + self.bulletX = 0 + self.bulletX1 = 0 + self.bulletY1 = 30 + self.bulletState = 'Ready' + #-----score----< + self.score_value=0 + self.j=0 + + + def score(self, scr): + font=pygame.font.SysFont('timesnewroman',30) + score=font.render('Score: '+ str(self.score_value),True, Color(255,255,255),Color(200,100,100)) + scr.blit(score,(10,10)) + + + def shooter(self, x, y, scr): + if x <= 0: + x = 0 + elif x >= 500: + x = 500 + elif y <= 400: + y=400 + elif y >= 550: + y=550 + scr.blit(pygame.image.load('../_static/human.png'), (x, y)) + + def enemy(self): + for i in range(8): + self.enemyImg.append(pygame.image.load('../_static/zomb.png')) + self.enemyX.append(random.randint(0, 500)) + self.enemyY.append(random.randint(5, 60)) + self.enemyX1.append(10) + self.enemyY1.append(40) + self.bulY1.append(2) + self.enemyBullet.append(pygame.image.load('../_static/BlueBar1.jpg')) + + def bullet(self, x, y, scr): + self.bulletState='fire' + scr.blit(pygame.image.load('../_static/bullet.png'), (x+8, y)) + + def collision_e_b(self, X, Y, i): + dist=math.sqrt((self.enemyX[i]-X)**2+(self.enemyY[i]-Y)**2) + if dist <=30: return True + else: return False + + def collision_E_S(self, x, y, i): + dist = math.sqrt((x-self.enemyX[i])**2+(y-self.enemyY[i])**2) + if dist <= 35: return True + else: return False + + def collision_enemyBul_S(self,enemybulX,enemyBulY,shooterX,shooterY): + dist=math.sqrt((enemybulX-shooterX)**2+(enemyBulY-shooterY)**2) + if dist <=24 : + scr.blit(pygame.image.load('../_static/blast.png'),(self.shooterX,self.shooterY)) + return True + else: return False + + + def over(): + scr.blit(pygame.image.load('../_static/bg2.jpg'),(0,0)) + scr.blit(game,(50,int(600/2))) + pygame.display.update() + + def over_helper(): + global timer1 + timer.clear_interval(timer1) + timer1 = None + over() + + + + scr = pygame.display.set_mode((550, 600)) + font=pygame.font.SysFont('timesnewroman',30) + game=font.render('Game Over -\n Press run to Play Again',True, Color(230,220,170)) + p1= Chaser() + p1.enemy() + p1.enemybulX=p1.enemyX[random.randint(0,7)] + + + def func(): + scr.blit(pygame.image.load('../_static/bg2.jpg'),(0,0)) + scr.blit(pygame.image.load('../_static/BlueBar1.jpg'),(p1.enemybulX+15,p1.enemyBulY+12)) + p1.enemyBulY+=24 + + if p1.enemyBulY>=600: + p1.enemyBulY=p1.enemyY[random.randint(0,7)] + p1.enemybulX=p1.enemyX[random.randint(0,7)] + + for event in pygame.event.get(): + #---Shooter Movement------< + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_LEFT: + p1.shooterX1 -= 15 + if event.key == pygame.K_RIGHT: + p1.shooterX1 += 15 + if event.key == pygame.K_UP: + p1.shooterY1-=15 + if event.key == pygame.K_DOWN: + p1.shooterY1+=15 + if event.key == pygame.K_SPACE: + if p1.bulletState == 'Ready': + p1.bulletX = p1.shooterX + p1.bulletY = p1.shooterY + p1.bullet(p1.bulletX, p1.bulletY, scr) + if event.type == pygame.KEYUP: + p1.shooterX1 = 0 + p1.shooterY1 = 0 + p1.shooterX += p1.shooterX1 + p1.shooterY += p1.shooterY1 + p1.shooter(p1.shooterX, p1.shooterY, scr) + + # ------Enemy-----< + for i in range(8): + p1.enemyX[i] += p1.enemyX1[i] + if p1.enemyX[i] <= 0: + p1.enemyX1[i] = 14 + p1.enemyY[i] += p1.enemyY1[i] + elif p1.enemyX[i] >= 500: + p1.enemyX1[i] =- 14 + p1.enemyY[i] += p1.enemyY1[i] + scr.blit(p1.enemyImg[i], (p1.enemyX[i], p1.enemyY[i])) + + #-------collision of bullet and enemy--------< + col = p1.collision_e_b(p1.bulletX, p1.bulletY, i) + if p1.bulletState == 'fire': + if col: + scr.blit(pygame.image.load('../_static/blast.png'),(p1.bulletX,p1.bulletY)) + p1.score_value += 1 + p1.bulletY = 500 + p1.bulletState='Ready' + p1.enemyX[i] = random.randint(0,500) + p1.enemyY[i] = random.randint(5,60) + + #-------collision of Shooter and enemy--------< + col2 = p1.collision_E_S(p1.shooterX, p1.shooterY, i) + if col2: + # scr.blit(pygame.image.load('Icons\\bgover.png'),(550,600)) + scr.blit(pygame.image.load('../_static/blast.png'),(p1.shooterX,p1.shooterY)) + over_helper() + + + + + #------Collision of Bottom and Enemy--------< + if p1.enemyY[i] >= 600: + p1.enemyX[i] = random.randint(0,500) + p1.enemyY[i] = random.randint(5,60) + + #-------Collision of EnemyBul and Shooter-------< + col3= p1.collision_enemyBul_S(p1.enemybulX,p1.enemyBulY,p1.shooterX,p1.shooterY) + if col3: + scr.blit(pygame.image.load('../_static/bg2.jpg'),(550,600)) + scr.blit(pygame.image.load('../_static/blast.png'),(p1.shooterX,p1.shooterY)) + over_helper() + + + + + #------Collision of Bottom and Enemy--------< + if p1.enemyY[i] >= 600: + p1.enemyX[i] = random.randint(0,500) + p1.enemyY[i] = random.randint(5,60) + + #-------Collision of EnemyBul and Shooter-------< + col3= p1.collision_enemyBul_S(p1.enemybulX,p1.enemyBulY,p1.shooterX,p1.shooterY) + if col3: + scr.blit(pygame.image.load('../_static/bg2.jpg'),(550,600)) + scr.blit(pygame.image.load('../_static/blast.png'),(p1.shooterX,p1.shooterY)) + over_helper() + # break + + #--------Shooter Bullet------< + if p1.bulletY <= 0: + p1.bulletY = 480 + p1.bulletState = 'Ready' + if p1.bulletState == 'fire': + p1.bullet(p1.bulletX, p1.bulletY, scr) + p1.bulletY -= p1.bulletY1 + + p1.score(scr) + p1.j+=1 + pygame.display.update() + + + + pygame.init() + + timer1 = timer.set_interval(func,80) diff --git a/293/_sources/challenges/Reto04.rst.txt b/293/_sources/challenges/Reto04.rst.txt new file mode 100644 index 0000000000..239214f784 --- /dev/null +++ b/293/_sources/challenges/Reto04.rst.txt @@ -0,0 +1,93 @@ +======================================= +Ejercicio de nombres de bebés de Google +======================================= + +.. datafile:: baby1990.html + :fromfile: ./_static/baby1990.html + :hide: + +.. datafile:: baby1996.html + :fromfile: ./_static/baby1996.html + :hide: + +.. datafile:: baby2002.html + :fromfile: ./_static/baby2002.html + :hide: + + +.. activecode:: ret04 + :nocodelens: + + + Dado un nombre de archivo para baby.html, devuelve una lista que comienza + con la cadena del año + seguido de las cadenas de rango de nombre en orden alfabético. + ['2006', 'Aaliyah 91', Aarón 57', 'Abagail 895', '...] + + Así es como se ve el html en los archivos baby.html: + +

Popularity in 1990

+ + 1MichaelJessica + + 2ChristopherAshley + + 3MatthewBrittany + + + ~~~~ + import re + + def extraer_nombres(filename): + + nombres = [] + + # abre y lee el archivo + # Code + + + # encontrar año + # Code + + + # encontrar nombres y rango + # Code + + + + return nombres + + def main(): + print (extraer_nombres('baby1990.html')) + + main() + + ==== + + from unittest.gui import TestCaseGui + + class myTests(TestCaseGui): + + def testOne(self): + + answer1996 = ['1996', 'Aaron 34', 'Abigail 32', 'Adam 39', 'Adrian 92', 'Alex 54', 'Alexa 100', 'Alexander 22', 'Alexandra 26', 'Alexandria 76', 'Alexis 8', 'Alicia 91', 'Allison 38', 'Alyssa 23', 'Amanda 13', 'Amber 27', 'Amy 88', 'Andrea 61', 'Andrew 10', 'Angela 90', 'Angelica 97', 'Anna 33', 'Anthony 19', 'Antonio 80', 'Ashley 3', 'Austin 9', 'Bailey 85', 'Benjamin 29', 'Blake 84', 'Bradley 83', 'Brandon 8', 'Breanna 74', 'Brian 36', 'Briana 72', 'Brianna 17', 'Brittany 14', 'Brooke 45', 'Bryan 66', 'Caitlin 84', 'Caleb 48', 'Cameron 49', 'Carlos 67', 'Caroline 78', 'Cassandra 89', 'Catherine 94', 'Charles 43', 'Chase 76', 'Chelsea 55', 'Cheyenne 69', 'Christian 24', 'Christina 57', 'Christopher 4', 'Cody 31', 'Connor 53', 'Corey 94', 'Courtney 21', 'Crystal 92', 'Dakota 58', 'Dalton 99', 'Daniel 11', 'Danielle 29', 'David 13', 'Destiny 56', 'Devin 59', 'Dustin 78', 'Dylan 33', 'Edward 95', 'Elijah 81', 'Elizabeth 10', 'Emily 1', 'Emma 53', 'Eric 35', 'Erica 79', 'Erin 51', 'Ethan 62', 'Evan 65', 'Gabriel 61', 'Gabrielle 54', 'Garrett 85', 'Grace 95', 'Gregory 98', 'Hailey 93', 'Haley 30', 'Hannah 7', 'Heather 71', 'Hunter 47', 'Ian 70', 'Isaac 86', 'Isaiah 71', 'Jack 89', 'Jacob 3', 'Jacqueline 68', 'James 17', 'Jamie 96', 'Jared 64', 'Jasmine 28', 'Jason 41', 'Jeffrey 72', 'Jenna 83', 'Jennifer 19', 'Jeremy 56', 'Jesse 51', 'Jessica 2', 'Jesus 74', 'John 15', 'Jonathan 21', 'Jordan 27', 'Jose 32', 'Joseph 12', 'Joshua 5', 'Juan 52', 'Julia 48', 'Justin 20', 'Kaitlyn 40', 'Katelyn 64', 'Katherine 31', 'Kathryn 87', 'Katie 82', 'Kayla 11', 'Kelly 73', 'Kelsey 36', 'Kenneth 77', 'Kevin 26', 'Kimberly 41', 'Kristen 70', 'Kyle 25', 'Laura 66', 'Lauren 16', 'Leah 98', 'Lindsey 86', 'Logan 42', 'Lucas 93', 'Luis 57', 'Luke 75', 'Mackenzie 75', 'Madeline 67', 'Madison 15', 'Malik 97', 'Marcus 87', 'Maria 37', 'Mariah 63', 'Marissa 59', 'Mark 55', 'Mary 44', 'Matthew 2', 'Megan 12', 'Melissa 42', 'Michael 1', 'Michelle 47', 'Miguel 91', 'Miranda 77', 'Mitchell 88', 'Molly 99', 'Monica 81', 'Morgan 25', 'Natalie 46', 'Nathan 37', 'Nathaniel 69', 'Nicholas 6', 'Nicole 22', 'Noah 50', 'Olivia 34', 'Paige 65', 'Patrick 44', 'Paul 79', 'Peter 96', 'Rachel 9', 'Rebecca 24', 'Richard 45', 'Robert 23', 'Ryan 16', 'Sabrina 58', 'Samantha 5', 'Samuel 30', 'Sara 50', 'Sarah 4', 'Savannah 43', 'Sean 46', 'Shannon 80', 'Shelby 35', 'Sierra 62', 'Stephanie 20', 'Stephen 60', 'Steven 38', 'Sydney 39', 'Tanner 90', 'Taylor 6', 'Thomas 28', 'Tiffany 52', 'Timothy 40', 'Travis 73', 'Trevor 63', 'Tristan 68', 'Tyler 7', 'Vanessa 60', 'Victor 100', 'Victoria 18', 'William 18', 'Zachary 14'] + self.assertEqual(extraer_nombres('baby1996.html'),answer1996) + + def testTwo(self): + + answer2002 = ['2002', 'Aaliyah 64', 'Aaron 44', 'Abigail 7', 'Adam 55', 'Adrian 73', 'Aidan 60', 'Alejandro 92', 'Alex 62', 'Alexa 69', 'Alexander 15', 'Alexandra 38', 'Alexis 5', 'Allison 44', 'Alyssa 12', 'Amanda 46', 'Amber 65', 'Andrea 56', 'Andrew 6', 'Angel 49', 'Angela 83', 'Angelina 75', 'Anna 20', 'Anthony 12', 'Antonio 85', 'Ariana 93', 'Ashley 6', 'Audrey 100', 'Austin 26', 'Autumn 73', 'Ava 82', 'Bailey 84', 'Benjamin 27', 'Blake 76', 'Brandon 20', 'Brian 51', 'Brianna 17', 'Brooke 52', 'Bryan 64', 'Bryce 97', 'Caleb 35', 'Cameron 39', 'Carlos 65', 'Caroline 67', 'Charles 58', 'Chase 82', 'Chloe 25', 'Christian 24', 'Christina 97', 'Christopher 8', 'Claire 95', 'Cody 71', 'Cole 69', 'Connor 47', 'Courtney 88', 'Daniel 10', 'Danielle 71', 'David 13', 'Destiny 34', 'Devin 74', 'Diego 98', 'Dominic 83', 'Dylan 23', 'Elijah 41', 'Elizabeth 11', 'Ella 89', 'Emily 1', 'Emma 4', 'Eric 52', 'Erin 72', 'Ethan 5', 'Evan 56', 'Evelyn 98', 'Faith 48', 'Gabriel 32', 'Gabriella 77', 'Gabrielle 66', 'Garrett 91', 'Gavin 61', 'Grace 15', 'Hailey 32', 'Haley 35', 'Hannah 3', 'Hayden 96', 'Hunter 38', 'Ian 67', 'Isaac 48', 'Isabel 85', 'Isabella 14', 'Isaiah 45', 'Jack 43', 'Jackson 50', 'Jacob 1', 'Jacqueline 81', 'Jada 78', 'Jade 86', 'Jaden 87', 'James 18', 'Jared 84', 'Jasmine 26', 'Jason 42', 'Jenna 47', 'Jennifer 28', 'Jeremiah 86', 'Jeremy 95', 'Jesse 90', 'Jessica 16', 'Jesus 66', 'Jocelyn 92', 'John 17', 'Jonathan 21', 'Jordan 37', 'Jose 30', 'Joseph 7', 'Joshua 3', 'Juan 54', 'Julia 33', 'Julian 78', 'Justin 22', 'Kaitlyn 31', 'Katelyn 53', 'Katherine 36', 'Kayla 19', 'Kaylee 57', 'Kevin 33', 'Kimberly 63', 'Kyle 40', 'Kylie 61', 'Lauren 13', 'Leah 87', 'Leslie 91', 'Lillian 96', 'Lily 79', 'Logan 29', 'Lucas 75', 'Luis 57', 'Luke 46', 'Mackenzie 42', 'Madeline 55', 'Madison 2', 'Makayla 49', 'Maria 40', 'Marissa 99', 'Mark 93', 'Mary 51', 'Mason 53', 'Matthew 4', 'Maya 90', 'Megan 22', 'Melanie 94', 'Melissa 80', 'Mia 43', 'Michael 2', 'Michelle 58', 'Miguel 88', 'Morgan 29', 'Natalie 30', 'Nathan 28', 'Nathaniel 63', 'Nicholas 9', 'Nicole 37', 'Noah 31', 'Olivia 10', 'Owen 94', 'Paige 50', 'Patrick 79', 'Rachel 24', 'Rebecca 54', 'Richard 77', 'Riley 76', 'Robert 34', 'Ryan 16', 'Samantha 9', 'Samuel 25', 'Sara 59', 'Sarah 8', 'Savannah 39', 'Sean 59', 'Sebastian 80', 'Seth 72', 'Shelby 74', 'Sierra 62', 'Sophia 27', 'Stephanie 41', 'Steven 68', 'Sydney 23', 'Taylor 18', 'Thomas 36', 'Timothy 70', 'Trevor 81', 'Trinity 70', 'Tyler 14', 'Vanessa 68', 'Victor 100', 'Victoria 21', 'William 11', 'Xavier 89', 'Zachary 19', 'Zoe 60'] + self.assertEqual(extraer_nombres('baby2002.html'),answer2002) + + myTests().main() + + +|Creative Commons License| +Este trabajo tiene una licencia de `Creative Commons Attribution 4.0 +Licencia Internacional `__. + +.. |Creative Commons License| image:: https://i.creativecommons.org/l/by/4.0/88x31.png + :target: http://creativecommons.org/licenses/by/4.0/ + +El ejercicio original se puede encontrar en `Ejercicio sobre Python con nombres de bebés `__. + + diff --git a/293/_sources/challenges/Reto04_en.rst.txt b/293/_sources/challenges/Reto04_en.rst.txt new file mode 100644 index 0000000000..2874a2a966 --- /dev/null +++ b/293/_sources/challenges/Reto04_en.rst.txt @@ -0,0 +1,95 @@ +========================= +Google babynames exercise +========================= + +.. datafile:: baby1990_en.html + :fromfile: ./_static/baby1990.html + :hide: + +.. datafile:: baby1996_en.html + :fromfile: ./_static/baby1996.html + :hide: + +.. datafile:: baby2002_en.html + :fromfile: ./_static/baby2002.html + :hide: + + + + +.. activecode:: ret04_en + :nocodelens: + + + Given a file name for baby.html, returns a list starting + with the year string + followed by the name-rank strings in alphabetical order. + ['2006', 'Aaliyah 91', Aaron 57', 'Abagail 895', ' ...] + + Here's what the html looks like in the baby.html files: + +

Popularity in 1990

+ + 1MichaelJessica + + 2ChristopherAshley + + 3MatthewBrittany + + + ~~~~ + import re + + def extract_names(filename): + + names = [] + + # Open and read the file. + # Code + + + # Find year + # Code + + + # Find names and rank + # Code + + + + return names + + def main(): + print (extract_names('baby1990_en.html')) + + main() + + ==== + + from unittest.gui import TestCaseGui + + class myTests(TestCaseGui): + + def testOne(self): + + answer1996 = ['1996', 'Aaron 34', 'Abigail 32', 'Adam 39', 'Adrian 92', 'Alex 54', 'Alexa 100', 'Alexander 22', 'Alexandra 26', 'Alexandria 76', 'Alexis 8', 'Alicia 91', 'Allison 38', 'Alyssa 23', 'Amanda 13', 'Amber 27', 'Amy 88', 'Andrea 61', 'Andrew 10', 'Angela 90', 'Angelica 97', 'Anna 33', 'Anthony 19', 'Antonio 80', 'Ashley 3', 'Austin 9', 'Bailey 85', 'Benjamin 29', 'Blake 84', 'Bradley 83', 'Brandon 8', 'Breanna 74', 'Brian 36', 'Briana 72', 'Brianna 17', 'Brittany 14', 'Brooke 45', 'Bryan 66', 'Caitlin 84', 'Caleb 48', 'Cameron 49', 'Carlos 67', 'Caroline 78', 'Cassandra 89', 'Catherine 94', 'Charles 43', 'Chase 76', 'Chelsea 55', 'Cheyenne 69', 'Christian 24', 'Christina 57', 'Christopher 4', 'Cody 31', 'Connor 53', 'Corey 94', 'Courtney 21', 'Crystal 92', 'Dakota 58', 'Dalton 99', 'Daniel 11', 'Danielle 29', 'David 13', 'Destiny 56', 'Devin 59', 'Dustin 78', 'Dylan 33', 'Edward 95', 'Elijah 81', 'Elizabeth 10', 'Emily 1', 'Emma 53', 'Eric 35', 'Erica 79', 'Erin 51', 'Ethan 62', 'Evan 65', 'Gabriel 61', 'Gabrielle 54', 'Garrett 85', 'Grace 95', 'Gregory 98', 'Hailey 93', 'Haley 30', 'Hannah 7', 'Heather 71', 'Hunter 47', 'Ian 70', 'Isaac 86', 'Isaiah 71', 'Jack 89', 'Jacob 3', 'Jacqueline 68', 'James 17', 'Jamie 96', 'Jared 64', 'Jasmine 28', 'Jason 41', 'Jeffrey 72', 'Jenna 83', 'Jennifer 19', 'Jeremy 56', 'Jesse 51', 'Jessica 2', 'Jesus 74', 'John 15', 'Jonathan 21', 'Jordan 27', 'Jose 32', 'Joseph 12', 'Joshua 5', 'Juan 52', 'Julia 48', 'Justin 20', 'Kaitlyn 40', 'Katelyn 64', 'Katherine 31', 'Kathryn 87', 'Katie 82', 'Kayla 11', 'Kelly 73', 'Kelsey 36', 'Kenneth 77', 'Kevin 26', 'Kimberly 41', 'Kristen 70', 'Kyle 25', 'Laura 66', 'Lauren 16', 'Leah 98', 'Lindsey 86', 'Logan 42', 'Lucas 93', 'Luis 57', 'Luke 75', 'Mackenzie 75', 'Madeline 67', 'Madison 15', 'Malik 97', 'Marcus 87', 'Maria 37', 'Mariah 63', 'Marissa 59', 'Mark 55', 'Mary 44', 'Matthew 2', 'Megan 12', 'Melissa 42', 'Michael 1', 'Michelle 47', 'Miguel 91', 'Miranda 77', 'Mitchell 88', 'Molly 99', 'Monica 81', 'Morgan 25', 'Natalie 46', 'Nathan 37', 'Nathaniel 69', 'Nicholas 6', 'Nicole 22', 'Noah 50', 'Olivia 34', 'Paige 65', 'Patrick 44', 'Paul 79', 'Peter 96', 'Rachel 9', 'Rebecca 24', 'Richard 45', 'Robert 23', 'Ryan 16', 'Sabrina 58', 'Samantha 5', 'Samuel 30', 'Sara 50', 'Sarah 4', 'Savannah 43', 'Sean 46', 'Shannon 80', 'Shelby 35', 'Sierra 62', 'Stephanie 20', 'Stephen 60', 'Steven 38', 'Sydney 39', 'Tanner 90', 'Taylor 6', 'Thomas 28', 'Tiffany 52', 'Timothy 40', 'Travis 73', 'Trevor 63', 'Tristan 68', 'Tyler 7', 'Vanessa 60', 'Victor 100', 'Victoria 18', 'William 18', 'Zachary 14'] + self.assertEqual(extract_names('baby1996_en.html'),answer1996) + + def testTwo(self): + + answer2002 = ['2002', 'Aaliyah 64', 'Aaron 44', 'Abigail 7', 'Adam 55', 'Adrian 73', 'Aidan 60', 'Alejandro 92', 'Alex 62', 'Alexa 69', 'Alexander 15', 'Alexandra 38', 'Alexis 5', 'Allison 44', 'Alyssa 12', 'Amanda 46', 'Amber 65', 'Andrea 56', 'Andrew 6', 'Angel 49', 'Angela 83', 'Angelina 75', 'Anna 20', 'Anthony 12', 'Antonio 85', 'Ariana 93', 'Ashley 6', 'Audrey 100', 'Austin 26', 'Autumn 73', 'Ava 82', 'Bailey 84', 'Benjamin 27', 'Blake 76', 'Brandon 20', 'Brian 51', 'Brianna 17', 'Brooke 52', 'Bryan 64', 'Bryce 97', 'Caleb 35', 'Cameron 39', 'Carlos 65', 'Caroline 67', 'Charles 58', 'Chase 82', 'Chloe 25', 'Christian 24', 'Christina 97', 'Christopher 8', 'Claire 95', 'Cody 71', 'Cole 69', 'Connor 47', 'Courtney 88', 'Daniel 10', 'Danielle 71', 'David 13', 'Destiny 34', 'Devin 74', 'Diego 98', 'Dominic 83', 'Dylan 23', 'Elijah 41', 'Elizabeth 11', 'Ella 89', 'Emily 1', 'Emma 4', 'Eric 52', 'Erin 72', 'Ethan 5', 'Evan 56', 'Evelyn 98', 'Faith 48', 'Gabriel 32', 'Gabriella 77', 'Gabrielle 66', 'Garrett 91', 'Gavin 61', 'Grace 15', 'Hailey 32', 'Haley 35', 'Hannah 3', 'Hayden 96', 'Hunter 38', 'Ian 67', 'Isaac 48', 'Isabel 85', 'Isabella 14', 'Isaiah 45', 'Jack 43', 'Jackson 50', 'Jacob 1', 'Jacqueline 81', 'Jada 78', 'Jade 86', 'Jaden 87', 'James 18', 'Jared 84', 'Jasmine 26', 'Jason 42', 'Jenna 47', 'Jennifer 28', 'Jeremiah 86', 'Jeremy 95', 'Jesse 90', 'Jessica 16', 'Jesus 66', 'Jocelyn 92', 'John 17', 'Jonathan 21', 'Jordan 37', 'Jose 30', 'Joseph 7', 'Joshua 3', 'Juan 54', 'Julia 33', 'Julian 78', 'Justin 22', 'Kaitlyn 31', 'Katelyn 53', 'Katherine 36', 'Kayla 19', 'Kaylee 57', 'Kevin 33', 'Kimberly 63', 'Kyle 40', 'Kylie 61', 'Lauren 13', 'Leah 87', 'Leslie 91', 'Lillian 96', 'Lily 79', 'Logan 29', 'Lucas 75', 'Luis 57', 'Luke 46', 'Mackenzie 42', 'Madeline 55', 'Madison 2', 'Makayla 49', 'Maria 40', 'Marissa 99', 'Mark 93', 'Mary 51', 'Mason 53', 'Matthew 4', 'Maya 90', 'Megan 22', 'Melanie 94', 'Melissa 80', 'Mia 43', 'Michael 2', 'Michelle 58', 'Miguel 88', 'Morgan 29', 'Natalie 30', 'Nathan 28', 'Nathaniel 63', 'Nicholas 9', 'Nicole 37', 'Noah 31', 'Olivia 10', 'Owen 94', 'Paige 50', 'Patrick 79', 'Rachel 24', 'Rebecca 54', 'Richard 77', 'Riley 76', 'Robert 34', 'Ryan 16', 'Samantha 9', 'Samuel 25', 'Sara 59', 'Sarah 8', 'Savannah 39', 'Sean 59', 'Sebastian 80', 'Seth 72', 'Shelby 74', 'Sierra 62', 'Sophia 27', 'Stephanie 41', 'Steven 68', 'Sydney 23', 'Taylor 18', 'Thomas 36', 'Timothy 70', 'Trevor 81', 'Trinity 70', 'Tyler 14', 'Vanessa 68', 'Victor 100', 'Victoria 21', 'William 11', 'Xavier 89', 'Zachary 19', 'Zoe 60'] + self.assertEqual(extract_names('baby2002_en.html'),answer2002) + + myTests().main() + + +|Creative Commons License| +This work is licensed under a `Creative Commons Attribution 4.0 +International License `__. + +.. |Creative Commons License| image:: https://i.creativecommons.org/l/by/4.0/88x31.png + :target: http://creativecommons.org/licenses/by/4.0/ + + + +Original exercise can be found at `Google Baby Names Exercise `__. diff --git a/293/_sources/challenges/Reto05.rst.txt b/293/_sources/challenges/Reto05.rst.txt new file mode 100644 index 0000000000..f5e138ffa4 --- /dev/null +++ b/293/_sources/challenges/Reto05.rst.txt @@ -0,0 +1,270 @@ +=========== +Reto PyMaze +=========== + +Objetivos: +---------- + +- **Completa la función solve_maze** + + Descripción: + + - Esta función toma el objeto laberinto como entrada y determina si hay una ruta desde el inicio (0,0) hasta el final (3) + - 1 es una pared + - 2 es un zombi + - 3 es el destino/fin + - 0 es todo el camino libre + +- **Completa la función de ejecución, que maneja eventos clave para mover a un jugador en el laberinto** + +- Complete la función `play_music`, que toma el audio del archivo `solve_maze.ogg` y lo reproduce al ejecutar el código + - la ruta del archivo para solveMusic es `../../audio/solve_maze.ogg` + +.. raw:: html + + + + + + + + +.. activecode:: ac_r04 + :language: python3 + :python3_interpreter: brython + + + ~~~~ + from browser import load, timer, window + load('../_static/game.js') + load('../_static/pygame.brython.js') + gjs = window.gamejs + gjs.image.preload(["../_static/zomb.png", '../_static/human.png', '../_static/dest.png']) + gjs.ready() + + ^^^^ + import pygame + from pygame.color import * + from pygame.locals import * + from pygame import mixer + + # game which has a maze and a player + # player has to reach the end of the maze + + class Maze: + + def __init__(self, maze=None): + self.maze = maze + self.rows = self.maze.__len__() + self.cols = self.maze[0].__len__() + + + def draw(self, screen): + + rows = self.rows + cols = self.cols + for i in range(rows): + for j in range(cols): + + if self.maze[i][j] == 1: + + pygame.draw.rect(screen, Color( + 0, 0, 0), pygame.Rect(j*50, i*50, 50, 50)) + + elif self.maze[i][j] == 2: + + zomb = pygame.image.load('../_static/zomb.png') + zomb = pygame.transform.scale(zomb, (50, 50)) + screen.blit(zomb, (j*50, i*50)) + + elif self.maze[i][j] == 3: + + dest = pygame.image.load('../_static/dest.png') + dest = pygame.transform.scale(dest, (50, 50)) + screen.blit(dest, (j*50, i*50)) + + else: + + pygame.draw.rect(screen, Color( + 255, 255, 255), pygame.Rect(j*50, i*50, 50, 50)) + + + def is_wall(self, x, y): + + if self.maze[y][x] == 1: + return True + else: + return False + + + def is_zombie(self, x, y): + + if self.maze[y][x] == 2: + return True + else: + return False + + + def is_destination(self, x, y): + + if self.maze[y][x] == 3: + return True + else: + return False + + + def is_out(self, x, y): + + if x < 0 or x >= self.cols or y < 0 or y >= self.rows: + return True + else: + return False + + + def is_safe(self, x, y): + + if self.maze[x][y] == 0 or self.maze[x][y] == 3: + return True + else: + return False + + + class Player: + + def __init__(self): + self.x = 0 + self.y = 0 + self.image = pygame.image.load('../_static/human.png') + self.image = pygame.transform.scale(self.image, (50, 50)) + self.startx = 0 + self.starty = 0 + self.endx = 10 + self.endy = 10 + + + def draw(self, screen, maze): + maze.draw(screen) + screen.blit(self.image, (self.x*50, self.y*50)) + + + def move(self, x, y, screen, maze): + + newX = self.x+x + newY = self.y+y + + if maze.is_out(newX, newY): + return + elif maze.is_wall(newX, newY): + return + elif maze.is_zombie(newX, newY): + over() + timer.clear_interval(timer1) + elif maze.is_destination(newX, newY): + over() + timer.clear_interval(timer1) + else: + self.x = newX + self.y = newY + maze.draw(screen) + screen.blit(self.image, (self.x*50, self.y*50)) + return + + + scr = pygame.display.set_mode((550, 550)) + font = pygame.font.SysFont('timesnewroman', 30) + game = font.render('Game Over -\n Press run to Play Again', True, Color(0, 0, 0)) + + def over(): + scr.blit(game, (0, 0)) + pygame.display.update() + + + playerMaze = [ + [0, 0, 0, 0, 0,0,0,0,1,0,1], + [1, 1, 0, 1, 1,1,1,1,1,0,1], + [0, 1, 0, 0, 0,0,0,0,1,0,1], + [0, 1, 0, 1, 1,1,1,0,2,0,1], + [0, 1, 0, 2, 0,0,1,0,1,0,1], + [0, 1, 0, 0, 0,0,1,0,1,0,1], + [0, 1, 1, 1, 1,0,1,0,0,0,1], + [0, 1, 0, 0, 0,0,0,0,0,1,1], + [0, 1, 1, 0, 1,1,1,1,0,1,1], + [0, 0, 0, 0, 0,0,0,0,0,0,1], + [1, 1, 1, 1, 1,1,1,1,1,3,1]]; + + maze = Maze(playerMaze) + player = Player() + player.draw(scr, maze) + + def run(): + # Controladores de eventos para eventos clave aquí + + pygame.display.update() + + + def play_music(): + # Reproduce música aquí usando pygame.mixer + + + pygame.init() + + timer1 = timer.set_interval(run, 100) + + def solve_maze(maze): + # devuelve True si el laberinto tiene una solución o + # Falso si no lo tiene + + + ==== + + import unittest + + class GradeMaze(unittest.TestCase): + + # This testcase has a solution, so it should return true + def test_one(self): + newMaze = [ + [0,0,0,0,0,0,1,0,0,0,1], + [1,1,2,1,1,0,1,1,1,1,0], + [0,1,0,0,0,0,0,0,0,1,0], + [0,1,0,1,1,2,1,1,0,1,0], + [0,1,0,1,0,0,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,0,3], + [0,1,0,1,0,1,0,1,1,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,1,1,0,1,0,1,1,1,0]]; + testMaze = Maze(newMaze) + + self.assertEqual(solve_maze(testMaze),True) + + # This testcase has no solution, so it should return false + def test_two(self): + newMaze = [ + [0,0,0,0,0,0,1,0,0,0,1], + [0,1,1,1,1,0,1,1,1,1,0], + [0,1,0,0,0,0,0,0,0,1,0], + [0,1,0,1,1,1,1,1,0,1,0], + [0,1,0,1,0,0,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,0,1], + [1,1,0,1,0,1,0,1,1,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,1,1,0,1,0,1,1,1,3]]; + testMaze = Maze(newMaze) + + self.assertEqual(solve_maze(testMaze),False) + + + suite = unittest.TestLoader().loadTestsFromTestCase(GradeMaze) + unittest.TextTestRunner(verbosity=0).run(suite) + + + diff --git a/293/_sources/challenges/Reto05_en.rst.txt b/293/_sources/challenges/Reto05_en.rst.txt new file mode 100644 index 0000000000..812ce6b237 --- /dev/null +++ b/293/_sources/challenges/Reto05_en.rst.txt @@ -0,0 +1,276 @@ +====== +PyMaze +====== + +Goals: +------ + +- **Complete the solve_maze function** + + Description: + + - This function takes maze object as input and determines if there is a path from start(0,0) to end(3) + - 1 is a wall + - 2 is a Zombie + - 3 is destination + - 0 is all the free path + +- **Complete the run function which handles key events to move player in maze** + +- Complete the `play_music` function which takes audio from file `solve_maze.ogg` and plays on running the code + - file path for solveMusic is `../../audio/solve_maze.ogg` + +.. raw:: html + + + + + + + + +.. activecode:: ac_r04_en + :language: python3 + :python3_interpreter: brython + + + ~~~~ + from browser import load, timer, window + load('../_static/game.js') + load('../_static/pygame.brython.js') + gjs = window.gamejs + gjs.image.preload(["../_static/zomb.png", '../_static/human.png', '../_static/dest.png']) + gjs.ready() + + ^^^^ + import pygame + from pygame.color import * + from pygame.locals import * + from pygame import mixer + + + # game which has a maze and a player + # player has to reach the end of the maze + class Maze: + + def __init__(self,maze=None): + self.maze = maze + self.rows = self.maze.__len__() + self.cols = self.maze[0].__len__() + + + def draw(self,screen): + + rows = self.rows + cols = self.cols + for i in range(rows): + for j in range(cols): + + if self.maze[i][j] == 1: + + pygame.draw.rect(screen, Color( + 0, 0, 0), pygame.Rect(j*50, i*50, 50, 50)) + + elif self.maze[i][j] == 2: + + zomb = pygame.image.load('../_static/zomb.png') + zomb = pygame.transform.scale(zomb, (50, 50)) + screen.blit(zomb, (j*50, i*50)) + + elif self.maze[i][j] == 3: + + dest = pygame.image.load('../_static/dest.png') + dest = pygame.transform.scale(dest, (50, 50)) + screen.blit(dest, (j*50, i*50)) + + else: + + pygame.draw.rect(screen, Color( + 255, 255, 255), pygame.Rect(j*50, i*50, 50, 50)) + + + def is_wall(self,x,y): + + if self.maze[y][x] == 1: + return True + else: + return False + + + def is_zombie(self,x,y): + + if self.maze[y][x] == 2: + return True + else: + return False + + + def is_destination(self,x,y): + + if self.maze[y][x] == 3: + return True + else: + return False + + + def is_out(self,x,y): + + if x<0 or x>=self.cols or y<0 or y >= self.rows: + return True + else: + return False + + + def is_safe(self,x,y): + + if self.maze[x][y] == 0 or self.maze[x][y] == 3: + return True + else: + return False + + + class Player: + + def __init__(self): + self.x=0 + self.y=0 + self.image = pygame.image.load('../_static/human.png') + self.image = pygame.transform.scale(self.image,(50,50)) + self.startx = 0 + self.starty = 0 + self.endx = 10 + self.endy = 10 + + + def draw(self,screen,maze): + maze.draw(screen) + screen.blit(self.image,(self.x*50,self.y*50)) + + + def move(self,x,y,screen,maze): + + newX = self.x+x + newY = self.y+y + + if maze.is_out(newX,newY): + return + elif maze.is_wall(newX,newY): + return + elif maze.is_zombie(newX,newY): + over() + timer.clear_interval(timer1) + elif maze.is_destination(newX,newY): + over() + timer.clear_interval(timer1) + else: + self.x = newX + self.y = newY + maze.draw(screen) + screen.blit(self.image,(self.x*50,self.y*50)) + return + + + scr = pygame.display.set_mode((550, 550)) + font = pygame.font.SysFont('timesnewroman',30) + game = font.render('Game Over -\n Press run to Play Again',True, Color(0,0,0)) + + def over(): + scr.blit(game,(0,0)) + pygame.display.update() + + + playerMaze = [ + [0,0,0,0,0,0,0,0,1,0,1], + [1,1,0,1,1,1,1,1,1,0,1], + [0,1,0,0,0,0,0,0,1,0,1], + [0,1,0,1,1,1,1,0,2,0,1], + [0,1,0,2,0,0,1,0,1,0,1], + [0,1,0,0,0,0,1,0,1,0,1], + [0,1,1,1,1,0,1,0,0,0,1], + [0,1,0,0,0,0,0,0,0,1,1], + [0,1,1,0,1,1,1,1,0,1,1], + [0,0,0,0,0,0,0,0,0,0,1], + [1,1,1,1,1,1,1,1,1,3,1]]; + + maze = Maze(playerMaze) + player = Player() + player.draw(scr,maze) + + def run(): + # Event handlers for Key events here + + + pygame.display.update() + + + + def play_music(): + # Play music here using pygame.mixer + + + + pygame.init() + + + + timer1 = timer.set_interval(run, 100) + + def solve_maze( maze ): + # returns True if the maze is Solvable or + # False if it doesn't + + + + ==== + + import unittest + + class GradeMaze(unittest.TestCase): + + # This testcase has a solution, so it should return true + def test_one(self): + newMaze = [ + [0,0,0,0,0,0,1,0,0,0,1], + [1,1,2,1,1,0,1,1,1,1,0], + [0,1,0,0,0,0,0,0,0,1,0], + [0,1,0,1,1,2,1,1,0,1,0], + [0,1,0,1,0,0,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,0,3], + [0,1,0,1,0,1,0,1,1,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,1,1,0,1,0,1,1,1,0]]; + testMaze = Maze(newMaze) + + self.assertEqual(solve_maze(testMaze),True) + + # This testcase has no solution, so it should return false + def test_two(self): + newMaze = [ + [0,0,0,0,0,0,1,0,0,0,1], + [0,1,1,1,1,0,1,1,1,1,0], + [0,1,0,0,0,0,0,0,0,1,0], + [0,1,0,1,1,1,1,1,0,1,0], + [0,1,0,1,0,0,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,0,1], + [1,1,0,1,0,1,0,1,1,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,0,1,0,1,0,1,0,1,0], + [0,1,1,1,0,1,0,1,1,1,3]]; + testMaze = Maze(newMaze) + + self.assertEqual(solve_maze(testMaze),False) + + + suite = unittest.TestLoader().loadTestsFromTestCase(GradeMaze) + unittest.TextTestRunner(verbosity=0).run(suite) + + + diff --git a/293/_sources/challenges/_static/baby1990.html.txt b/293/_sources/challenges/_static/baby1990.html.txt new file mode 100644 index 0000000000..853d369a53 --- /dev/null +++ b/293/_sources/challenges/_static/baby1990.html.txt @@ -0,0 +1,229 @@ +<head><title>Popular Baby Names</title> + + <meta name="dc.language" scheme="ISO639-2" content="eng"> + + <meta name="dc.creator" content="OACT"> + + <meta name="lead_content_manager" content="JeffK"> + + <meta name="coder" content="JeffK"> + + <meta name="dc.date.reviewed" scheme="ISO8601" content="2005-12-30"> + + <link rel="stylesheet" href="../OACT/templatefiles/master.css" type="text/css" media="screen"> + + <link rel="stylesheet" href="../OACT/templatefiles/custom.css" type="text/css" media="screen"> + + <link rel="stylesheet" href="../OACT/templatefiles/print.css" type="text/css" media="print"> + + </head> + + <body bgcolor="#ffffff" text="#000000" topmargin="1" leftmargin="0"> + + <table width="100%" border="0" cellspacing="0" cellpadding="4"> + + <tbody> + + <tr><td class="sstop" valign="bottom" align="left" width="25%"> + + Social Security Online + + </td><td valign="bottom" class="titletext"> + + <!-- sitetitle -->Popular Baby Names + + </td> + + </tr> + + <tr bgcolor="#333366"><td colspan="2" height="2"></td></tr> + + <tr><td class="graystars" width="25%" valign="top"> + + <a href="../OACT/babynames/">Popular Baby Names</a></td><td valign="top"> + + <a href="http://www.ssa.gov/"><img src="/templateimages/tinylogo.gif" + + width="52" height="47" align="left" + + alt="SSA logo: link to Social Security home page" border="0"></a><a name="content"></a> + + <h1>Popular Names by Birth Year</h1>September 12, 2007</td> + + </tr> + + <tr bgcolor="#333366"><td colspan="2" height="1"></td></tr> + + </tbody></table> + + <table width="100%" border="0" cellspacing="0" cellpadding="4" summary="formatting"> + + <tr valign="top"><td width="25%" class="greycell"> + + <a href="../OACT/babynames/background.html">Background information</a> + + <p><br /> + + &nbsp; Select another <label for="yob">year of birth</label>?<br /> + + <form method="post" action="/cgi-bin/popularnames.cgi"> + + &nbsp; <input type="text" name="year" id="yob" size="4" value="1990"> + + <input type="hidden" name="top" value="1000"> + + <input type="hidden" name="number" value=""> + + &nbsp; <input type="submit" value=" Go "></form> + + </td><td> + + <h3 align="center">Popularity in 1990</h3> + + <p align="center"> + + <table width="48%" border="1" bordercolor="#aaabbb" + + cellpadding="2" cellspacing="0" summary="Popularity for top 1000"> + + <tr align="center" valign="bottom"> + + <th scope="col" width="12%" bgcolor="#efefef">Rank</th> + + <th scope="col" width="41%" bgcolor="#99ccff">Male name</th> + + <th scope="col" bgcolor="pink" width="41%">Female name</th></tr> + + <tr align="right"><td>1</td><td>Michael</td><td>Jessica</td> + + <tr align="right"><td>2</td><td>Christopher</td><td>Ashley</td> + + <tr align="right"><td>3</td><td>Matthew</td><td>Brittany</td> + + <tr align="right"><td>4</td><td>Joshua</td><td>Amanda</td> + + <tr align="right"><td>5</td><td>Daniel</td><td>Samantha</td> + + <tr align="right"><td>6</td><td>David</td><td>Sarah</td> + + <tr align="right"><td>7</td><td>Andrew</td><td>Stephanie</td> + + <tr align="right"><td>8</td><td>James</td><td>Jennifer</td> + + <tr align="right"><td>9</td><td>Justin</td><td>Elizabeth</td> + + <tr align="right"><td>10</td><td>Joseph</td><td>Lauren</td> + + <tr align="right"><td>11</td><td>Ryan</td><td>Megan</td> + + <tr align="right"><td>12</td><td>John</td><td>Emily</td> + + <tr align="right"><td>13</td><td>Robert</td><td>Nicole</td> + + <tr align="right"><td>14</td><td>Nicholas</td><td>Kayla</td> + + <tr align="right"><td>15</td><td>Anthony</td><td>Amber</td> + + <tr align="right"><td>16</td><td>William</td><td>Rachel</td> + + <tr align="right"><td>17</td><td>Jonathan</td><td>Courtney</td> + + <tr align="right"><td>18</td><td>Kyle</td><td>Danielle</td> + + <tr align="right"><td>19</td><td>Brandon</td><td>Heather</td> + + <tr align="right"><td>20</td><td>Jacob</td><td>Melissa</td> + + <tr align="right"><td>21</td><td>Tyler</td><td>Rebecca</td> + + <tr align="right"><td>22</td><td>Zachary</td><td>Michelle</td> + + <tr align="right"><td>23</td><td>Kevin</td><td>Tiffany</td> + + <tr align="right"><td>24</td><td>Eric</td><td>Chelsea</td> + + <tr align="right"><td>25</td><td>Steven</td><td>Christina</td> + + <tr align="right"><td>26</td><td>Thomas</td><td>Katherine</td> + + <tr align="right"><td>27</td><td>Brian</td><td>Alyssa</td> + + <tr align="right"><td>28</td><td>Alexander</td><td>Jasmine</td> + + <tr align="right"><td>29</td><td>Jordan</td><td>Laura</td> + + <tr align="right"><td>30</td><td>Timothy</td><td>Hannah</td> + + <tr align="right"><td>31</td><td>Cody</td><td>Kimberly</td> + + <tr align="right"><td>32</td><td>Adam</td><td>Kelsey</td> + + <tr align="right"><td>33</td><td>Benjamin</td><td>Victoria</td> + + <tr align="right"><td>34</td><td>Aaron</td><td>Sara</td> + + <tr align="right"><td>35</td><td>Richard</td><td>Mary</td> + + <tr align="right"><td>36</td><td>Patrick</td><td>Erica</td> + + <tr align="right"><td>37</td><td>Sean</td><td>Alexandra</td> + + <tr align="right"><td>38</td><td>Charles</td><td>Amy</td> + + <tr align="right"><td>39</td><td>Stephen</td><td>Crystal</td> + + <tr align="right"><td>40</td><td>Jeremy</td><td>Andrea</td> + + <tr align="right"><td>41</td><td>Jose</td><td>Kelly</td> + + <tr align="right"><td>42</td><td>Travis</td><td>Kristen</td> + + <tr align="right"><td>43</td><td>Jeffrey</td><td>Erin</td> + + <tr align="right"><td>44</td><td>Nathan</td><td>Brittney</td> + + <tr align="right"><td>45</td><td>Samuel</td><td>Anna</td> + + <tr align="right"><td>46</td><td>Mark</td><td>Taylor</td> + + <tr align="right"><td>47</td><td>Jason</td><td>Maria</td> + + <tr align="right"><td>48</td><td>Jesse</td><td>Allison</td> + + <tr align="right"><td>49</td><td>Paul</td><td>Cassandra</td> + + <tr align="right"><td>50</td><td>Dustin</td><td>Caitlin</td> + + <tr><td colspan="3"><small>Note: Rank 1 is the most popular, + + rank 2 is the next most popular, and so forth. + + </table></p> + + </td></tr></table> + + <table class="printhide" width="100%" border="0" cellpadding="1" cellspacing="0"> + + <tr bgcolor="#333366"><td height="1" valign="top" height="1" colspan="3"></td></tr> + + <tr><td width="26%" valign="middle">&nbsp;<a href="http://www.firstgov.gov"><img + + src="/templateimages/firstgov3.gif" width="72" height="15" + + alt="Link to FirstGov.gov: U.S. Government portal" border="0"></a></td><td valign="top" class="seventypercent"> + + <a href="http://www.ssa.gov/privacy.html">Privacy Policy</a>&nbsp; + + | <a href="http://www.ssa.gov/websitepolicies.htm">Website Policies + + &amp; Other Important Information</a>&nbsp; + + | <a href="http://www.ssa.gov/sitemap.htm">Site Map</a></td> + + </tr> + + </table> + + </body></html> + + diff --git a/293/_sources/challenges/_static/baby1996.html.txt b/293/_sources/challenges/_static/baby1996.html.txt new file mode 100644 index 0000000000..34897e3d2b --- /dev/null +++ b/293/_sources/challenges/_static/baby1996.html.txt @@ -0,0 +1,329 @@ +<head><title>Popular Baby Names</title> + + <meta name="dc.language" scheme="ISO639-2" content="eng"> + + <meta name="dc.creator" content="OACT"> + + <meta name="lead_content_manager" content="JeffK"> + + <meta name="coder" content="JeffK"> + + <meta name="dc.date.reviewed" scheme="ISO8601" content="2005-12-30"> + + <link rel="stylesheet" href="../OACT/templatefiles/master.css" type="text/css" media="screen"> + + <link rel="stylesheet" href="../OACT/templatefiles/custom.css" type="text/css" media="screen"> + + <link rel="stylesheet" href="../OACT/templatefiles/print.css" type="text/css" media="print"> + + </head> + + <body bgcolor="#ffffff" text="#000000" topmargin="1" leftmargin="0"> + + <table width="100%" border="0" cellspacing="0" cellpadding="4"> + + <tbody> + + <tr><td class="sstop" valign="bottom" align="left" width="25%"> + + Social Security Online + + </td><td valign="bottom" class="titletext"> + + <!-- sitetitle -->Popular Baby Names + + </td> + + </tr> + + <tr bgcolor="#333366"><td colspan="2" height="2"></td></tr> + + <tr><td class="graystars" width="25%" valign="top"> + + <a href="../OACT/babynames/">Popular Baby Names</a></td><td valign="top"> + + <a href="http://www.ssa.gov/"><img src="/templateimages/tinylogo.gif" + + width="52" height="47" align="left" + + alt="SSA logo: link to Social Security home page" border="0"></a><a name="content"></a> + + <h1>Popular Names by Birth Year</h1>September 12, 2007</td> + + </tr> + + <tr bgcolor="#333366"><td colspan="2" height="1"></td></tr> + + </tbody></table> + + <table width="100%" border="0" cellspacing="0" cellpadding="4" summary="formatting"> + + <tr valign="top"><td width="25%" class="greycell"> + + <a href="../OACT/babynames/background.html">Background information</a> + + <p><br /> + + &nbsp; Select another <label for="yob">year of birth</label>?<br /> + + <form method="post" action="/cgi-bin/popularnames.cgi"> + + &nbsp; <input type="text" name="year" id="yob" size="4" value="1996"> + + <input type="hidden" name="top" value="1000"> + + <input type="hidden" name="number" value=""> + + &nbsp; <input type="submit" value=" Go "></form> + + </td><td> + + <h3 align="center">Popularity in 1996</h3> + + <p align="center"> + + <table width="48%" border="1" bordercolor="#aaabbb" + + cellpadding="2" cellspacing="0" summary="Popularity for top 1000"> + + <tr align="center" valign="bottom"> + + <th scope="col" width="12%" bgcolor="#efefef">Rank</th> + + <th scope="col" width="41%" bgcolor="#99ccff">Male name</th> + + <th scope="col" bgcolor="pink" width="41%">Female name</th></tr> + + <tr align="right"><td>1</td><td>Michael</td><td>Emily</td> + + <tr align="right"><td>2</td><td>Matthew</td><td>Jessica</td> + + <tr align="right"><td>3</td><td>Jacob</td><td>Ashley</td> + + <tr align="right"><td>4</td><td>Christopher</td><td>Sarah</td> + + <tr align="right"><td>5</td><td>Joshua</td><td>Samantha</td> + + <tr align="right"><td>6</td><td>Nicholas</td><td>Taylor</td> + + <tr align="right"><td>7</td><td>Tyler</td><td>Hannah</td> + + <tr align="right"><td>8</td><td>Brandon</td><td>Alexis</td> + + <tr align="right"><td>9</td><td>Austin</td><td>Rachel</td> + + <tr align="right"><td>10</td><td>Andrew</td><td>Elizabeth</td> + + <tr align="right"><td>11</td><td>Daniel</td><td>Kayla</td> + + <tr align="right"><td>12</td><td>Joseph</td><td>Megan</td> + + <tr align="right"><td>13</td><td>David</td><td>Amanda</td> + + <tr align="right"><td>14</td><td>Zachary</td><td>Brittany</td> + + <tr align="right"><td>15</td><td>John</td><td>Madison</td> + + <tr align="right"><td>16</td><td>Ryan</td><td>Lauren</td> + + <tr align="right"><td>17</td><td>James</td><td>Brianna</td> + + <tr align="right"><td>18</td><td>William</td><td>Victoria</td> + + <tr align="right"><td>19</td><td>Anthony</td><td>Jennifer</td> + + <tr align="right"><td>20</td><td>Justin</td><td>Stephanie</td> + + <tr align="right"><td>21</td><td>Jonathan</td><td>Courtney</td> + + <tr align="right"><td>22</td><td>Alexander</td><td>Nicole</td> + + <tr align="right"><td>23</td><td>Robert</td><td>Alyssa</td> + + <tr align="right"><td>24</td><td>Christian</td><td>Rebecca</td> + + <tr align="right"><td>25</td><td>Kyle</td><td>Morgan</td> + + <tr align="right"><td>26</td><td>Kevin</td><td>Alexandra</td> + + <tr align="right"><td>27</td><td>Jordan</td><td>Amber</td> + + <tr align="right"><td>28</td><td>Thomas</td><td>Jasmine</td> + + <tr align="right"><td>29</td><td>Benjamin</td><td>Danielle</td> + + <tr align="right"><td>30</td><td>Samuel</td><td>Haley</td> + + <tr align="right"><td>31</td><td>Cody</td><td>Katherine</td> + + <tr align="right"><td>32</td><td>Jose</td><td>Abigail</td> + + <tr align="right"><td>33</td><td>Dylan</td><td>Anna</td> + + <tr align="right"><td>34</td><td>Aaron</td><td>Olivia</td> + + <tr align="right"><td>35</td><td>Eric</td><td>Shelby</td> + + <tr align="right"><td>36</td><td>Brian</td><td>Kelsey</td> + + <tr align="right"><td>37</td><td>Nathan</td><td>Maria</td> + + <tr align="right"><td>38</td><td>Steven</td><td>Allison</td> + + <tr align="right"><td>39</td><td>Adam</td><td>Sydney</td> + + <tr align="right"><td>40</td><td>Timothy</td><td>Kaitlyn</td> + + <tr align="right"><td>41</td><td>Jason</td><td>Kimberly</td> + + <tr align="right"><td>42</td><td>Logan</td><td>Melissa</td> + + <tr align="right"><td>43</td><td>Charles</td><td>Savannah</td> + + <tr align="right"><td>44</td><td>Patrick</td><td>Mary</td> + + <tr align="right"><td>45</td><td>Richard</td><td>Brooke</td> + + <tr align="right"><td>46</td><td>Sean</td><td>Natalie</td> + + <tr align="right"><td>47</td><td>Hunter</td><td>Michelle</td> + + <tr align="right"><td>48</td><td>Caleb</td><td>Julia</td> + + <tr align="right"><td>49</td><td>Cameron</td><td>Jordan</td> + + <tr align="right"><td>50</td><td>Noah</td><td>Sara</td> + + <tr align="right"><td>51</td><td>Jesse</td><td>Erin</td> + + <tr align="right"><td>52</td><td>Juan</td><td>Tiffany</td> + + <tr align="right"><td>53</td><td>Connor</td><td>Emma</td> + + <tr align="right"><td>54</td><td>Alex</td><td>Gabrielle</td> + + <tr align="right"><td>55</td><td>Mark</td><td>Chelsea</td> + + <tr align="right"><td>56</td><td>Jeremy</td><td>Destiny</td> + + <tr align="right"><td>57</td><td>Luis</td><td>Christina</td> + + <tr align="right"><td>58</td><td>Dakota</td><td>Sabrina</td> + + <tr align="right"><td>59</td><td>Devin</td><td>Marissa</td> + + <tr align="right"><td>60</td><td>Stephen</td><td>Vanessa</td> + + <tr align="right"><td>61</td><td>Gabriel</td><td>Andrea</td> + + <tr align="right"><td>62</td><td>Ethan</td><td>Sierra</td> + + <tr align="right"><td>63</td><td>Trevor</td><td>Mariah</td> + + <tr align="right"><td>64</td><td>Jared</td><td>Katelyn</td> + + <tr align="right"><td>65</td><td>Evan</td><td>Paige</td> + + <tr align="right"><td>66</td><td>Bryan</td><td>Laura</td> + + <tr align="right"><td>67</td><td>Carlos</td><td>Madeline</td> + + <tr align="right"><td>68</td><td>Tristan</td><td>Jacqueline</td> + + <tr align="right"><td>69</td><td>Nathaniel</td><td>Cheyenne</td> + + <tr align="right"><td>70</td><td>Ian</td><td>Kristen</td> + + <tr align="right"><td>71</td><td>Isaiah</td><td>Heather</td> + + <tr align="right"><td>72</td><td>Jeffrey</td><td>Briana</td> + + <tr align="right"><td>73</td><td>Travis</td><td>Kelly</td> + + <tr align="right"><td>74</td><td>Jesus</td><td>Breanna</td> + + <tr align="right"><td>75</td><td>Luke</td><td>Mackenzie</td> + + <tr align="right"><td>76</td><td>Chase</td><td>Alexandria</td> + + <tr align="right"><td>77</td><td>Kenneth</td><td>Miranda</td> + + <tr align="right"><td>78</td><td>Dustin</td><td>Caroline</td> + + <tr align="right"><td>79</td><td>Paul</td><td>Erica</td> + + <tr align="right"><td>80</td><td>Antonio</td><td>Shannon</td> + + <tr align="right"><td>81</td><td>Elijah</td><td>Monica</td> + + <tr align="right"><td>82</td><td>Taylor</td><td>Katie</td> + + <tr align="right"><td>83</td><td>Bradley</td><td>Jenna</td> + + <tr align="right"><td>84</td><td>Blake</td><td>Caitlin</td> + + <tr align="right"><td>85</td><td>Garrett</td><td>Bailey</td> + + <tr align="right"><td>86</td><td>Isaac</td><td>Lindsey</td> + + <tr align="right"><td>87</td><td>Marcus</td><td>Kathryn</td> + + <tr align="right"><td>88</td><td>Mitchell</td><td>Amy</td> + + <tr align="right"><td>89</td><td>Jack</td><td>Cassandra</td> + + <tr align="right"><td>90</td><td>Tanner</td><td>Angela</td> + + <tr align="right"><td>91</td><td>Miguel</td><td>Alicia</td> + + <tr align="right"><td>92</td><td>Adrian</td><td>Crystal</td> + + <tr align="right"><td>93</td><td>Lucas</td><td>Hailey</td> + + <tr align="right"><td>94</td><td>Corey</td><td>Catherine</td> + + <tr align="right"><td>95</td><td>Edward</td><td>Grace</td> + + <tr align="right"><td>96</td><td>Peter</td><td>Jamie</td> + + <tr align="right"><td>97</td><td>Malik</td><td>Angelica</td> + + <tr align="right"><td>98</td><td>Gregory</td><td>Leah</td> + + <tr align="right"><td>99</td><td>Dalton</td><td>Molly</td> + + <tr align="right"><td>100</td><td>Victor</td><td>Alexa</td> + + <tr><td colspan="3"><small>Note: Rank 1 is the most popular, + + rank 2 is the next most popular, and so forth. + + </table></p> + + </td></tr></table> + + <table class="printhide" width="100%" border="0" cellpadding="1" cellspacing="0"> + + <tr bgcolor="#333366"><td height="1" valign="top" height="1" colspan="3"></td></tr> + + <tr><td width="26%" valign="middle">&nbsp;<a href="http://www.firstgov.gov"><img + + src="/templateimages/firstgov3.gif" width="72" height="15" + + alt="Link to FirstGov.gov: U.S. Government portal" border="0"></a></td><td valign="top" class="seventypercent"> + + <a href="http://www.ssa.gov/privacy.html">Privacy Policy</a>&nbsp; + + | <a href="http://www.ssa.gov/websitepolicies.htm">Website Policies + + &amp; Other Important Information</a>&nbsp; + + | <a href="http://www.ssa.gov/sitemap.htm">Site Map</a></td> + + </tr> + + </table> + + </body></html> + + diff --git a/293/_sources/challenges/_static/baby2002.html.txt b/293/_sources/challenges/_static/baby2002.html.txt new file mode 100644 index 0000000000..e61aa70f20 --- /dev/null +++ b/293/_sources/challenges/_static/baby2002.html.txt @@ -0,0 +1,328 @@ +<head><title>Popular Baby Names</title> + +<meta name="dc.language" scheme="ISO639-2" content="eng"> + +<meta name="dc.creator" content="OACT"> + +<meta name="lead_content_manager" content="JeffK"> + +<meta name="coder" content="JeffK"> + +<meta name="dc.date.reviewed" scheme="ISO8601" content="2005-12-30"> + +<link rel="stylesheet" href="../OACT/templatefiles/master.css" type="text/css" media="screen"> + +<link rel="stylesheet" href="../OACT/templatefiles/custom.css" type="text/css" media="screen"> + +<link rel="stylesheet" href="../OACT/templatefiles/print.css" type="text/css" media="print"> + +</head> + +<body bgcolor="#ffffff" text="#000000" topmargin="1" leftmargin="0"> + +<table width="100%" border="0" cellspacing="0" cellpadding="4"> + + <tbody> + + <tr><td class="sstop" valign="bottom" align="left" width="25%"> + + Social Security Online + + </td><td valign="bottom" class="titletext"> + + <!-- sitetitle -->Popular Baby Names + + </td> + + </tr> + + <tr bgcolor="#333366"><td colspan="2" height="2"></td></tr> + + <tr><td class="graystars" width="25%" valign="top"> + + <a href="../OACT/babynames/">Popular Baby Names</a></td><td valign="top"> + + <a href="http://www.ssa.gov/"><img src="/templateimages/tinylogo.gif" + + width="52" height="47" align="left" + + alt="SSA logo: link to Social Security home page" border="0"></a><a name="content"></a> + + <h1>Popular Names by Birth Year</h1>September 12, 2007</td> + + </tr> + + <tr bgcolor="#333366"><td colspan="2" height="1"></td></tr> + +</tbody></table> + +<table width="100%" border="0" cellspacing="0" cellpadding="4" summary="formatting"> + + <tr valign="top"><td width="25%" class="greycell"> + + <a href="../OACT/babynames/background.html">Background information</a> + + <p><br /> + + &nbsp; Select another <label for="yob">year of birth</label>?<br /> + + <form method="post" action="/cgi-bin/popularnames.cgi"> + + &nbsp; <input type="text" name="year" id="yob" size="4" value="2002"> + + <input type="hidden" name="top" value="1000"> + + <input type="hidden" name="number" value=""> + + &nbsp; <input type="submit" value=" Go "></form> + + </td><td> + +<h3 align="center">Popularity in 2002</h3> + +<p align="center"> + +<table width="48%" border="1" bordercolor="#aaabbb" + + cellpadding="2" cellspacing="0" summary="Popularity for top 1000"> + +<tr align="center" valign="bottom"> + + <th scope="col" width="12%" bgcolor="#efefef">Rank</th> + + <th scope="col" width="41%" bgcolor="#99ccff">Male name</th> + +<th scope="col" bgcolor="pink" width="41%">Female name</th></tr> + +<tr align="right"><td>1</td><td>Jacob</td><td>Emily</td> + +<tr align="right"><td>2</td><td>Michael</td><td>Madison</td> + +<tr align="right"><td>3</td><td>Joshua</td><td>Hannah</td> + +<tr align="right"><td>4</td><td>Matthew</td><td>Emma</td> + +<tr align="right"><td>5</td><td>Ethan</td><td>Alexis</td> + +<tr align="right"><td>6</td><td>Andrew</td><td>Ashley</td> + +<tr align="right"><td>7</td><td>Joseph</td><td>Abigail</td> + +<tr align="right"><td>8</td><td>Christopher</td><td>Sarah</td> + +<tr align="right"><td>9</td><td>Nicholas</td><td>Samantha</td> + +<tr align="right"><td>10</td><td>Daniel</td><td>Olivia</td> + +<tr align="right"><td>11</td><td>William</td><td>Elizabeth</td> + +<tr align="right"><td>12</td><td>Anthony</td><td>Alyssa</td> + +<tr align="right"><td>13</td><td>David</td><td>Lauren</td> + +<tr align="right"><td>14</td><td>Tyler</td><td>Isabella</td> + +<tr align="right"><td>15</td><td>Alexander</td><td>Grace</td> + +<tr align="right"><td>16</td><td>Ryan</td><td>Jessica</td> + +<tr align="right"><td>17</td><td>John</td><td>Brianna</td> + +<tr align="right"><td>18</td><td>James</td><td>Taylor</td> + +<tr align="right"><td>19</td><td>Zachary</td><td>Kayla</td> + +<tr align="right"><td>20</td><td>Brandon</td><td>Anna</td> + +<tr align="right"><td>21</td><td>Jonathan</td><td>Victoria</td> + +<tr align="right"><td>22</td><td>Justin</td><td>Megan</td> + +<tr align="right"><td>23</td><td>Dylan</td><td>Sydney</td> + +<tr align="right"><td>24</td><td>Christian</td><td>Rachel</td> + +<tr align="right"><td>25</td><td>Samuel</td><td>Chloe</td> + +<tr align="right"><td>26</td><td>Austin</td><td>Jasmine</td> + +<tr align="right"><td>27</td><td>Benjamin</td><td>Sophia</td> + +<tr align="right"><td>28</td><td>Nathan</td><td>Jennifer</td> + +<tr align="right"><td>29</td><td>Logan</td><td>Morgan</td> + +<tr align="right"><td>30</td><td>Jose</td><td>Natalie</td> + +<tr align="right"><td>31</td><td>Noah</td><td>Kaitlyn</td> + +<tr align="right"><td>32</td><td>Gabriel</td><td>Hailey</td> + +<tr align="right"><td>33</td><td>Kevin</td><td>Julia</td> + +<tr align="right"><td>34</td><td>Robert</td><td>Destiny</td> + +<tr align="right"><td>35</td><td>Caleb</td><td>Haley</td> + +<tr align="right"><td>36</td><td>Thomas</td><td>Katherine</td> + +<tr align="right"><td>37</td><td>Jordan</td><td>Nicole</td> + +<tr align="right"><td>38</td><td>Hunter</td><td>Alexandra</td> + +<tr align="right"><td>39</td><td>Cameron</td><td>Savannah</td> + +<tr align="right"><td>40</td><td>Kyle</td><td>Maria</td> + +<tr align="right"><td>41</td><td>Elijah</td><td>Stephanie</td> + +<tr align="right"><td>42</td><td>Jason</td><td>Mackenzie</td> + +<tr align="right"><td>43</td><td>Jack</td><td>Mia</td> + +<tr align="right"><td>44</td><td>Aaron</td><td>Allison</td> + +<tr align="right"><td>45</td><td>Isaiah</td><td>Jordan</td> + +<tr align="right"><td>46</td><td>Luke</td><td>Amanda</td> + +<tr align="right"><td>47</td><td>Connor</td><td>Jenna</td> + +<tr align="right"><td>48</td><td>Isaac</td><td>Faith</td> + +<tr align="right"><td>49</td><td>Angel</td><td>Makayla</td> + +<tr align="right"><td>50</td><td>Jackson</td><td>Paige</td> + +<tr align="right"><td>51</td><td>Brian</td><td>Mary</td> + +<tr align="right"><td>52</td><td>Eric</td><td>Brooke</td> + +<tr align="right"><td>53</td><td>Mason</td><td>Katelyn</td> + +<tr align="right"><td>54</td><td>Juan</td><td>Rebecca</td> + +<tr align="right"><td>55</td><td>Adam</td><td>Madeline</td> + +<tr align="right"><td>56</td><td>Evan</td><td>Andrea</td> + +<tr align="right"><td>57</td><td>Luis</td><td>Kaylee</td> + +<tr align="right"><td>58</td><td>Charles</td><td>Michelle</td> + +<tr align="right"><td>59</td><td>Sean</td><td>Sara</td> + +<tr align="right"><td>60</td><td>Aidan</td><td>Zoe</td> + +<tr align="right"><td>61</td><td>Gavin</td><td>Kylie</td> + +<tr align="right"><td>62</td><td>Alex</td><td>Sierra</td> + +<tr align="right"><td>63</td><td>Nathaniel</td><td>Kimberly</td> + +<tr align="right"><td>64</td><td>Bryan</td><td>Aaliyah</td> + +<tr align="right"><td>65</td><td>Carlos</td><td>Amber</td> + +<tr align="right"><td>66</td><td>Jesus</td><td>Gabrielle</td> + +<tr align="right"><td>67</td><td>Ian</td><td>Caroline</td> + +<tr align="right"><td>68</td><td>Steven</td><td>Vanessa</td> + +<tr align="right"><td>69</td><td>Cole</td><td>Alexa</td> + +<tr align="right"><td>70</td><td>Timothy</td><td>Trinity</td> + +<tr align="right"><td>71</td><td>Cody</td><td>Danielle</td> + +<tr align="right"><td>72</td><td>Seth</td><td>Erin</td> + +<tr align="right"><td>73</td><td>Adrian</td><td>Autumn</td> + +<tr align="right"><td>74</td><td>Devin</td><td>Shelby</td> + +<tr align="right"><td>75</td><td>Lucas</td><td>Angelina</td> + +<tr align="right"><td>76</td><td>Blake</td><td>Riley</td> + +<tr align="right"><td>77</td><td>Richard</td><td>Gabriella</td> + +<tr align="right"><td>78</td><td>Julian</td><td>Jada</td> + +<tr align="right"><td>79</td><td>Patrick</td><td>Lily</td> + +<tr align="right"><td>80</td><td>Sebastian</td><td>Melissa</td> + +<tr align="right"><td>81</td><td>Trevor</td><td>Jacqueline</td> + +<tr align="right"><td>82</td><td>Chase</td><td>Ava</td> + +<tr align="right"><td>83</td><td>Dominic</td><td>Angela</td> + +<tr align="right"><td>84</td><td>Jared</td><td>Bailey</td> + +<tr align="right"><td>85</td><td>Antonio</td><td>Isabel</td> + +<tr align="right"><td>86</td><td>Jeremiah</td><td>Jade</td> + +<tr align="right"><td>87</td><td>Jaden</td><td>Leah</td> + +<tr align="right"><td>88</td><td>Miguel</td><td>Courtney</td> + +<tr align="right"><td>89</td><td>Xavier</td><td>Ella</td> + +<tr align="right"><td>90</td><td>Jesse</td><td>Maya</td> + +<tr align="right"><td>91</td><td>Garrett</td><td>Leslie</td> + +<tr align="right"><td>92</td><td>Alejandro</td><td>Jocelyn</td> + +<tr align="right"><td>93</td><td>Mark</td><td>Ariana</td> + +<tr align="right"><td>94</td><td>Owen</td><td>Melanie</td> + +<tr align="right"><td>95</td><td>Jeremy</td><td>Claire</td> + +<tr align="right"><td>96</td><td>Hayden</td><td>Lillian</td> + +<tr align="right"><td>97</td><td>Bryce</td><td>Christina</td> + +<tr align="right"><td>98</td><td>Diego</td><td>Evelyn</td> + +<tr align="right"><td>99</td><td>Riley</td><td>Marissa</td> + +<tr align="right"><td>100</td><td>Victor</td><td>Audrey</td> + +<tr><td colspan="3"><small>Note: Rank 1 is the most popular, + +rank 2 is the next most popular, and so forth. + +</table></p> + +</td></tr></table> + +<table class="printhide" width="100%" border="0" cellpadding="1" cellspacing="0"> + + <tr bgcolor="#333366"><td height="1" valign="top" height="1" colspan="3"></td></tr> + + <tr><td width="26%" valign="middle">&nbsp;<a href="http://www.firstgov.gov"><img + + src="/templateimages/firstgov3.gif" width="72" height="15" + + alt="Link to FirstGov.gov: U.S. Government portal" border="0"></a></td><td valign="top" class="seventypercent"> + + <a href="http://www.ssa.gov/privacy.html">Privacy Policy</a>&nbsp; + + | <a href="http://www.ssa.gov/websitepolicies.htm">Website Policies + + &amp; Other Important Information</a>&nbsp; + + | <a href="http://www.ssa.gov/sitemap.htm">Site Map</a></td> + + </tr> + +</table> + +</body></html> + diff --git a/293/_sources/index.rst.txt b/293/_sources/index.rst.txt new file mode 100644 index 0000000000..f78eb8314d --- /dev/null +++ b/293/_sources/index.rst.txt @@ -0,0 +1,34 @@ +===================== +Bienvenido a PyZombis +===================== +----------------------------- +un curso de Python en español +----------------------------- + + +.. youtube:: YO58tXerKDc + :divid: Introducción + :height: 315 + :width: 560 + + +.. raw:: html + + + + + +Contenidos: + +.. toctree:: + :maxdepth: 1 + + index_es + index_en \ No newline at end of file diff --git a/293/_sources/index_en.rst.txt b/293/_sources/index_en.rst.txt new file mode 100644 index 0000000000..07582b56c2 --- /dev/null +++ b/293/_sources/index_en.rst.txt @@ -0,0 +1,59 @@ +=================== +Welcome to PyZombis +=================== +-------------------------- +A Python Course in Spanish +-------------------------- + +Contents: + +.. toctree:: + :maxdepth: 1 + + lectures/TWP05/toctree_en + lectures/TWP10/toctree_en + lectures/TWP15/toctree_en + lectures/TWP17/toctree_en + lectures/TWP18/toctree_en + lectures/TWP20/toctree_en + lectures/TWP23/toctree_en + lectures/TWP25/toctree_en + lectures/TWP30/toctree_en + lectures/TWP33/toctree_en + lectures/TWP35/toctree_en + lectures/TWP37/toctree_en + lectures/TWP38/toctree_en + lectures/TWP40/toctree_en + lectures/TWP42/toctree_en + lectures/TWP45/toctree_en + lectures/TWP47/toctree_en + lectures/TWP50/toctree_en + lectures/TWP52_en + lectures/TWP54/toctree_en + lectures/TWP56/toctree_en + lectures/TWP58/toctree_en + lectures/TWP60/toctree_en + lectures/TWP65/toctree_en + quiz/Quiz1_en.rst + quiz/Quiz2_en.rst + quiz/Quiz3_en.rst + quiz/Quiz4_en.rst + quiz/Quiz5_en.rst + quiz/Quiz6_en.rst + quiz/Quiz7_en.rst + quiz/Quiz8_en.rst + quiz/Quiz9_en.rst + quiz/Quiz10_en.rst + quiz/Quiz11_en.rst + quiz/Quiz12_en.rst + quiz/Quiz13_en.rst + quiz/QuizExtras_en.rst + quiz/QuizExtras2_en.rst + challenges/Reto01_en.rst + challenges/Reto02.rst + challenges/Reto03_en.rst + challenges/Reto04_en.rst + challenges/Reto05_en.rst + + + diff --git a/293/_sources/index_es.rst.txt b/293/_sources/index_es.rst.txt new file mode 100644 index 0000000000..ecf1551c24 --- /dev/null +++ b/293/_sources/index_es.rst.txt @@ -0,0 +1,56 @@ +===================== +Bienvenido a PyZombis +===================== +----------------------------- +un curso de Python en español +----------------------------- + +Contenidos: + +.. toctree:: + :maxdepth: 1 + + lectures/TWP05/toctree + lectures/TWP10/toctree + lectures/TWP15/toctree + lectures/TWP17/toctree + lectures/TWP18/toctree + lectures/TWP20/toctree + lectures/TWP23/toctree + lectures/TWP25/toctree + lectures/TWP30/toctree + lectures/TWP33/toctree + lectures/TWP35/toctree + lectures/TWP37/toctree + lectures/TWP38/toctree + lectures/TWP40/toctree + lectures/TWP42/toctree + lectures/TWP45/toctree + lectures/TWP47/toctree + lectures/TWP50/toctree + lectures/TWP52 + lectures/TWP54/toctree + lectures/TWP56/toctree + lectures/TWP58/toctree + lectures/TWP60/toctree + lectures/TWP65/toctree + quiz/Quiz1.rst + quiz/Quiz2.rst + quiz/Quiz3.rst + quiz/Quiz4.rst + quiz/Quiz5.rst + quiz/Quiz6.rst + quiz/Quiz7.rst + quiz/Quiz8.rst + quiz/Quiz9.rst + quiz/Quiz10.rst + quiz/Quiz11.rst + quiz/Quiz12.rst + quiz/Quiz13.rst + quiz/QuizExtras.rst + quiz/QuizExtras2.rst + challenges/Reto01.rst + challenges/Reto02.rst + challenges/Reto03.rst + challenges/Reto04.rst + challenges/Reto05.rst diff --git a/293/_sources/lectures/TWP05/TWP05_1.rst.txt b/293/_sources/lectures/TWP05/TWP05_1.rst.txt new file mode 100644 index 0000000000..39c87530d1 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_1.rst.txt @@ -0,0 +1,21 @@ +Primer programa +================= + +.. code-block:: python + + >>> print ("¡hola mundo!") + ¡hola mundo! + ++ Este programa tiene solo una línea de código ++ Tenga en cuenta que las comillas no aparecen en la salida ++ Necesitamos marcar o limitar el comienzo y el final de nuestros mensajes + con un símbolo, en este caso, las comillas + +**¡Ahora inténtelo por su propia cuenta!** + ++ Escriba ``print("primer mensaje")`` en el intérprete de abajo y compruebe que recibe la salida de su mensaje sin comillas. + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html diff --git a/293/_sources/lectures/TWP05/TWP05_10.rst.txt b/293/_sources/lectures/TWP05/TWP05_10.rst.txt new file mode 100644 index 0000000000..fec5838234 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_10.rst.txt @@ -0,0 +1,40 @@ +Expresiones lógicas +=================== + ++ Podemos combinar los operadores lógicos para formar expresiones lógicas complejas ++ El orden de evaluación es: ``not`` > ``and`` > ``or``. Esto significa que en una + expresión se evalúa primero el operador lógico ``not``, después ``and`` y por último ``or``. + +Veamos un ejemplo + +.. codelens:: cl_l05_10a + + print(not False or False and True) + print(False or True and True) + print(not False and True or False) + +Ejemplo +------- + ++ La condición para otorgar un préstamo de compra de una motocicleta son: tener un + salario mayor que $1,000.00 y ser mayor de 18 años. Compruebe si José puede obtener el + préstamo + +.. codelens:: cl_l05_10b + + salario = 500.0 + edad = 20 + print(salario > 1000 and edad > 18) + +Ejemplo +------- + ++ Verifique si un estudiante aprobó dado que obtuvo una puntuación promedio de 5.8 en + el programa de ejercicios y obtuvo un puntaje promedio de 7 en las pruebas + +.. codelens:: cl_l05_10c + + ep = 5.8 + p = 7 + aprobado = ep >= 6 and p >= 6 + print(aprobado) diff --git a/293/_sources/lectures/TWP05/TWP05_10_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_10_en.rst.txt new file mode 100644 index 0000000000..9b86e0461f --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_10_en.rst.txt @@ -0,0 +1,36 @@ +Logical expressions +=================== + ++ We can combine logical operators to form complex logical expressions ++ The evaluation order is: ``not`` > ``and`` > ``or``. This means that in an expression, the ``not`` logical operator is evaluated first, then ``and``, and finally ``or``. + +Let's see an example: + +.. codelens:: cl_l05_10a_en + + print(not False or False and True) + print(False or True and True) + print(not False and True or False) + +Example +------- + ++ The conditions for granting a motorcycle purchase loan are: having a salary greater than $1,000.00 and being over 18 years old. Check if José can get the loan: + +.. codelens:: cl_l05_10b_en + + salary = 500.0 + age = 20 + print(salary > 1000 and age > 18) + +Example +------- + ++ Check if a student passed given that they obtained an average score of 5.8 in the exercise program and obtained an average score of 7 in the tests: + +.. codelens:: cl_l05_10c_en + + ep = 5.8 + p = 7 + passed = ep >= 6 and p >= 6 + print(passed) \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_11.rst.txt b/293/_sources/lectures/TWP05/TWP05_11.rst.txt new file mode 100644 index 0000000000..2b9e3de3e5 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_11.rst.txt @@ -0,0 +1,44 @@ +Variable String +=============== + ++ Almacene cadenas como nombres y texto en general ++ Llamamos cadenas a una secuencia de símbolos como + letras, números, signos de puntuación, etc. ++ Para diferenciar sus comandos de una cadena, usamos comillas en + principio y fin + +.. codelens:: cl_l05_11a + + texto = "Joaquin y Maria comen pan" + print(texto) + ++ Tenga en cuenta que no hay problema al usar espacios para separar palabras ++ Una cadena tiene una longitud asociada ++ Podemos obtener el tamaño a través de la función de ``len`` incorporada en Python + +.. codelens:: cl_l05_11b + + texto = "Joaquin y Maria comen pan" + print(len(texto)) + ++ Podemos acceder a los caracteres en la cadena usando un número entero + para representar su posición en la cadena ++ Este número se llama índice y comenzamos a contar desde cero ++ Accedemos al carácter proporcionando el índice entre corchetes ``[]`` + +.. codelens:: cl_l05_11c + + texto = "Joaquin y Maria comen pan" + print(texto[0]) + print(texto[2]) + print(texto[5]) + print(texto[10]) + print(texto[15]) + ++ **Precaución**: no podemos acceder a un índice mayor que la cantidad de + caracteres de cadena + +.. codelens:: cl_l05_11d + + texto = "Juan y Maria comen pan" + print(texto[22]) diff --git a/293/_sources/lectures/TWP05/TWP05_11_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_11_en.rst.txt new file mode 100644 index 0000000000..cc2196d4d2 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_11_en.rst.txt @@ -0,0 +1,42 @@ +String Variable +=============== + ++ Store strings as names and general text ++ We call strings a sequence of symbols such as letters, numbers, punctuation marks, etc. ++ To differentiate its commands from a string, we use quotation marks at the beginning and end + +.. codelens:: cl_l05_11a_en + + text = "Joaquin and Maria eat bread" + print(text) + ++ Note that there is no problem using spaces to separate words ++ A string has an associated length ++ We can obtain the size through the ``len`` function built into Python + +.. codelens:: cl_l05_11b_en + + text = "Joaquin and Maria eat bread" + print(len(text)) + ++ We can access the characters in the string using an integer + to represent their position in the string ++ This number is called an index and we start counting from zero ++ We access the character providing the index between brackets ``[]`` + +.. codelens:: cl_l05_11c_en + + text = "Joaquin and Maria eat bread" + print(text[0]) + print(text[2]) + print(text[5]) + print(text[10]) + print(text[15]) + ++ **Caution**: we cannot access an index greater than the amount of + characters in the string + +.. codelens:: cl_l05_11d_en + + text = "Juan and Maria eat bread" + print(text[22]) \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_12.rst.txt b/293/_sources/lectures/TWP05/TWP05_12.rst.txt new file mode 100644 index 0000000000..11dc9de412 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_12.rst.txt @@ -0,0 +1,86 @@ +Operaciones con strings +======================= + ++ Las operaciones básicas son corte, concatenación y composición. ++ La operación corte le permite usar parte de la cadena ++ La operación concatenación en cambio sirve para unir dos o más cadenas ++ Por último la composición se usa mucho cuando enviamos mensajes a la pantalla + y consiste en usar cadenas como patrones donde podemos insertar datos + + +Concatenación +------------- + +.. codelens:: cl_l05_12a + + a = "Papa" + b = "cuando nace" + print(a + b) + print(a * 3) + +Corte +----- + ++ Podemos realizar la operación de corte utilizando ``[indice_comienzo:indice_fin]`` + +.. codelens:: cl_l05_12b + + x = "0123456789" + print(x[0:2]) + print(x[1:2]) + print(x[2:4]) + print(x[0:5]) + print(x[1:8]) + ++ Podemos omitir índices, sustituyendo el índice correspondiente y + también podemos tener índices negativos: -1 último, -2 penúltimo + +.. codelens:: cl_l05_12c + + x = "0123456789" + print(x[:2]) + print(x[4:]) + print(x[4:-1]) + print(x[-4:-1]) + print(x[:]) + +Composición +----------- + ++ Unir cadenas múltiples no siempre es práctico ++ Podemos usar marcadores de posición para reemplazar valores dentro de cadenas + +.. codelens:: cl_l05_12d + + edad = 20 + print("Juan tiene %d años" % edad) + ++ Los marcadores principales son ``%d`` para números enteros, ``%s`` para + cadenas y ``%f`` para números de punto flotante ++ % 03d completo con ceros adicionales ++ % 3d significa tres posiciones sin ceros adicionales + +.. codelens:: cl_l05_12e + + edad = 20 + print("[%03d]" % edad) + print("[%3d]" % edad) + ++ ``%5.2f`` significa 5 caracteres en total y 2 decimales + +.. codelens:: cl_l05_12f + + print("$%5.2f pesos" % 23) + +f-strings +--------- + ++ Otra manera de unir cadenas es mediante las f-strings ++ Todo lo que esté entre llaves {} se reemplazará si se definió anteriormente. En el ejemplo .2f significa dos lugares decimales. + +.. activecode:: ac_l05_12 + :nocodelens: + :stdin: + + precio = 10.123 + print(f"El precio es: ${precio:.2f}") diff --git a/293/_sources/lectures/TWP05/TWP05_12_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_12_en.rst.txt new file mode 100644 index 0000000000..f610ae4ccc --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_12_en.rst.txt @@ -0,0 +1,86 @@ +String Operations +================= + ++ The basic operations are slicing, concatenation, and formatting. ++ Slicing allows you to use part of a string ++ Concatenation, in contrast, is used to join two or more strings ++ Finally, formatting is used heavily when sending messages to the console + and consists of using strings as templates where we can insert data + + +Concatenation +------------- + +.. codelens:: cl_l05_12a_en + + a = "Potato" + b = "when born" + print(a + b) + print(a * 3) + +Slicing +------- + ++ We can perform the slicing operation using ``[start_index:end_index]`` + +.. codelens:: cl_l05_12b_en + + x = "0123456789" + print(x[0:2]) + print(x[1:2]) + print(x[2:4]) + print(x[0:5]) + print(x[1:8]) + ++ We can omit indices, replacing the corresponding index, and + we can also have negative indices: -1 last, -2 penultimate + +.. codelens:: cl_l05_12c_en + + x = "0123456789" + print(x[:2]) + print(x[4:]) + print(x[4:-1]) + print(x[-4:-1]) + print(x[:]) + +Formatting +---------- + ++ Joining multiple strings is not always practical ++ We can use placeholders to replace values within strings + +.. codelens:: cl_l05_12d_en + + age = 20 + print("Juan is %d years old" % age) + ++ The main placeholders are ``%d`` for integers, ``%s`` for + strings, and ``%f`` for floating-point numbers ++ % 03d complete with additional zeros ++ % 3d means three positions without additional zeros + +.. codelens:: cl_l05_12e_en + + age = 20 + print("[%03d]" % age) + print("[%3d]" % age) + ++ ``%5.2f`` means 5 characters in total and 2 decimals + +.. codelens:: cl_l05_12f_en + + print("$%5.2f pesos" % 23) + +f-strings +--------- + ++ Another way to join strings is through f-strings ++ Everything inside braces {} will be replaced if previously defined. In the example, .2f means two decimal places. + +.. activecode:: ac_l05_12_en + :nocodelens: + :stdin: + + price = 10.123 + print(f"The price is: ${price:.2f}") \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_13.rst.txt b/293/_sources/lectures/TWP05/TWP05_13.rst.txt new file mode 100644 index 0000000000..8b30e8df8f --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_13.rst.txt @@ -0,0 +1,17 @@ +Cambiar variables a lo largo del tiempo +======================================= + ++ Un programa se ejecuta línea por línea. ++ Por lo tanto, las variables pueden cambiar a lo largo de la ejecución de su + programa + +.. codelens:: cl_l05_13 + + deuda = 0 + compra = 100 + deuda = deuda + compra + compra = 200 + deuda = deuda + compra + compra = 300 + deuda = deuda + compra + print(deuda) diff --git a/293/_sources/lectures/TWP05/TWP05_13_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_13_en.rst.txt new file mode 100644 index 0000000000..bcb4f78f4d --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_13_en.rst.txt @@ -0,0 +1,16 @@ +Changing variables over time +============================= + ++ A program is executed line by line. ++ Therefore, the variables can change throughout the execution of your program. + +.. codelens:: cl_l05_13_en + + debt = 0 + purchase = 100 + debt = debt + purchase + purchase = 200 + debt = debt + purchase + purchase = 300 + debt = debt + purchase + print(debt) \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_14.rst.txt b/293/_sources/lectures/TWP05/TWP05_14.rst.txt new file mode 100644 index 0000000000..c11bd7887c --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_14.rst.txt @@ -0,0 +1,32 @@ +Prueba de escritorio o simulación +================================= + ++ Comprender que el valor de las variables puede cambiar durante la ejecución de + un programa no es tan natural, pero es fundamental a la hora de programar ++ Un programa no puede leerse como texto, sino con cuidado + analizando línea por línea ++ Puedes entrenar con lápiz, borrador y papel + + +.. table:: **Prueba de mesa o simulación** + :widths: auto + :align: left + + ====== ====== ======== + deuda compra Pantalla + ====== ====== ======== + -0- -100- 600 + -100- -200- + -300- 300 + 600 + ====== ====== ======== + + +No tengas prisa por la prueba de escritorio +------------------------------------------- + +.. image:: ../img/TWP05_035.jpeg + :height: 13.6cm + :width: 20.42cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP05/TWP05_14_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_14_en.rst.txt new file mode 100644 index 0000000000..ef405d96aa --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_14_en.rst.txt @@ -0,0 +1,30 @@ +Desktop testing or simulation +================================= + ++ Understanding that the value of variables can change during program execution is not so natural, but it is fundamental when programming ++ A program cannot be read as text, but carefully analyzing line by line ++ You can practice with pencil, eraser, and paper + + +.. table:: **Desktop testing or simulation** + :widths: auto + :align: left + + ===== ======== ====== + debt purchase Screen + ===== ======== ====== + -0- -100- 600 + -100- -200- + -300- 300 + 600 + ===== ======== ====== + + +Don't rush desktop testing +-------------------------------- + +.. image:: ../img/TWP05_035.jpeg + :height: 13.6cm + :width: 20.42cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_15.rst.txt b/293/_sources/lectures/TWP05/TWP05_15.rst.txt new file mode 100644 index 0000000000..ebeefc24d1 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_15.rst.txt @@ -0,0 +1,46 @@ +Entrada de datos +================ + ++ Hasta ahora nuestros programas han trabajado con valores conocidos. ++ Comenzaremos a obtener los valores durante la ejecución de los programas. + +.. activecode:: ac_l05_15a + :nocodelens: + :stdin: + + nombre = input("Escriba su nombre: ") + print(f"Hola {nombre}!") + + +Conversión de entrada de datos +------------------------------ + ++ La función ``input`` solo devuelve cadenas ++ Usamos la función ``int()`` y ``float()`` para convertir un valor a un entero o + a un valor de punto flotante respectivamente + +.. activecode:: ac_l05_15b + :nocodelens: + :stdin: + + valor_unitario = float(input("Valor de una rosquilla: ")) + n = int(input("Número de rosquillas: ")) + print(f"Valor total: ${(n * valor_unitario)}") + + +Error común +----------- + ++ Abrir dos paréntesis y cerrar solo uno. ++ Esto mismo nos puede ocurrir con las llaves, corchetes, comillas, entre otros caracteres. ``{}``, ``[]``, ``" "`` siempre que abrimos uno debemos acordarnos de cerrarlo. ++ El error terminará en lo siguiente: + +.. code-block:: python + + >>> valor_unitario = float(input("Valor de una rosquilla: ") + File , line 1 + valor_unitario = float(input("Valor de una rosquilla: ") + ^ + SyntaxError: '( was never closed + ++ Siempre que la línea parezca correcta, consulte la línea inmediatamente anterior diff --git a/293/_sources/lectures/TWP05/TWP05_15_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_15_en.rst.txt new file mode 100644 index 0000000000..a12abdf03a --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_15_en.rst.txt @@ -0,0 +1,46 @@ +Data Input +========== + ++ Up until now our programs have worked with known values. ++ We will begin to obtain the values during the execution of the programs. + +.. activecode:: ac_l05_15a_en + :nocodelens: + :stdin: + + name = input("Write your name: ") + print(f"Hello {name}!") + + +Data Input Conversion +--------------------- + ++ The ``input`` function only returns strings. ++ We use the ``int()`` and ``float()`` functions to convert a value to an integer or + a floating-point value respectively. + +.. activecode:: ac_l05_15b_en + :nocodelens: + :stdin: + + unit_value = float(input("Value of a donut: ")) + n = int(input("Number of donuts: ")) + print(f"Total value: ${(n * unit_value)}") + + +Common Error +------------ + ++ Opening two parentheses and closing only one. ++ The same can happen to us with braces, brackets, quotes, among other characters. ``{}``, ``[]``, ``" "`` whenever we open one we must remember to close it. ++ The error will end with the following: + +.. code-block:: python + + >>> unit_value = float(input("Value of a donut: ") + File , line 1 + unit_value = float(input("Value of a donut: ") + ^ + SyntaxError: '( was never closed + ++ Whenever the line seems correct, check the immediately previous line. \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_16.rst.txt b/293/_sources/lectures/TWP05/TWP05_16.rst.txt new file mode 100644 index 0000000000..06936f0e84 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_16.rst.txt @@ -0,0 +1,51 @@ +Lista de Ejercicios +=================== + +Utilice el intérprete de modo interactivo aquí abajo para solucionar los siguientes ejercicios. + +#. Su salario actual es de $6500. Calcule su nuevo salario con un aumento del 5% +#. Muestre su nombre en la pantalla +#. Calcule la suma de tres variables +#. ¿Qué sucede si escribo textos en las tres variables anteriores? +#. Indique el tipo de los siguientes valores: ``5``, ``5.0``, ``4.3``, ``-2``, ``100``, ``1.333``, ``"10"`` +#. Experimente en el intérprete interactivo de Python utilizar ``type(x)`` donde ``x`` es cada uno de los valores anteriores +#. ¿Es posible calcular 2 elevado a un millón? +#. Pruebe asignar a una variable ``saludo`` la cadena de caracteres ``'hola'`` (string). +#. Solicite que el usuario ingrese su nombre, y guardelo en otra variable ``nombre`` +#. ¿Es posible unir ambas cadenas de caracteres (strings) ``saludo`` y ``nombre``? +#. Intente obtener la longitud de las cadena de caracteres con ``len(x)`` + + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + +.. raw:: html + +
+ +.. reveal:: cl_l05_16a + + #. Para calcular un aumento del 5% podemos multiplicar nuestro valor por 1.05, por lo que tenemos: ``6500*1.05 = 6825.0``. Entonces, después del aumento, su salario será de $6825. + #. ``print("tu nombre")`` + #. Suponga las variables ``x = 1``, ``y = 2`` y ``z = 3``. Para sumarlas es necesario usar el símbolo + de la siguiente manera: ``x + y + z``. Que resulta en el valor 6. + #. Supongamos ahora que las variables son ``x = "Me"``, ``y = "gusta"`` y ``z = "Python"``. Si sumamos estas variables tendremos la respuesta: "MegustaPython". + #. Las respuestas correctas son int, float, float, int, int, float y str. + #. Para conocer el tipo de una variable usamos el método ``type`` de la siguiente manera: ``type(5)``. Este código devolverá ```` indicando que esta variable es de tipo entero. + #. Es posible, para eso solo haz ``2**1000000`` y tendrás el resultado. + #. Para crear una variable de tipo string, podemos escribir su valor entre comillas simples o dobles: ``saludo = "Hello"`` o ``saludo = 'Hello'``. + #. ``nombre = input("Escribe tu nombre: ")`` + #. Sí. Cuando agregamos dos cadenas, Python las concatena. Supongamos las variables ``x = "saludo"`` e ``y = "nombre"``. Si sumamos ``x + y`` tendremos como respuesta “saludonombre”. + #. Supongamos que queremos la longitud de la cadena “saludo”. Para saber esto hacemos ``len(saludo)`` cuyo resultado es 6. + + + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +“La vida es como andar en bicicleta. Para mantener el equilibrio, debes seguir moviéndote”. - Einstein + diff --git a/293/_sources/lectures/TWP05/TWP05_16_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_16_en.rst.txt new file mode 100644 index 0000000000..0a902c8ad5 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_16_en.rst.txt @@ -0,0 +1,48 @@ +Exercise List +============= + +Use the interactive interpreter below to solve the following exercises. + +#. Your current salary is $6500. Calculate your new salary with a 5% increase. +#. Display your name on the screen. +#. Calculate the sum of three variables. +#. What happens if you write text in the previous three variables? +#. Indicate the type of the following values: ``5``, ``5.0``, ``4.3``, ``-2``, ``100``, ``1.333``, ``"10"`` +#. Experiment in the interactive Python interpreter using ``type(x)`` where ``x`` is each of the previous values. +#. Is it possible to calculate 2 to the power of one million? +#. Try assigning a variable ``greeting`` the string ``'hello'``. +#. Ask the user to enter their name and store it in another variable ``name``. +#. Is it possible to join both strings of characters (strings) ``greeting`` and ``name``? +#. Try to get the length of the character strings with ``len(x)`` + + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + +.. raw:: html + +
+ +.. reveal:: cl_l05_16a_en + + #. To calculate a 5% increase we can multiply our value by 1.05, so we have: ``6500*1.05 = 6825.0``. Then, after the increase, your salary will be $6825. + #. ``print("your name")`` + #. Suppose the variables ``x = 1``, ``y = 2`` and ``z = 3``. To add them up, use the + symbol as follows: ``x + y + z``, which results in the value 6. + #. Suppose now that the variables are ``x = "Me"``, ``y = "like"`` and ``z = "Python"``. If we add these variables we will get the answer: "MelikePython". + #. The correct answers are int, float, float, int, int, float, and str. + #. To know the type of a variable, we use the ``type`` method as follows: ``type(5)``. This code will return ```` indicating that this variable is of integer type. + #. It is possible, just do ``2**1000000`` and you will get the result. + #. To create a string variable, we can write its value between single or double quotes: ``greeting = "Hello"`` or ``greeting = 'Hello'``. + #. ``name = input("Enter your name: ")`` + #. Yes. When we add two strings, Python concatenates them. Let's suppose the variables ``x = "greeting"`` and ``y = "name"``. If we add ``x + y``, we will get "greetingname" as the answer. + #. Suppose we want the length of the string "greeting". To find out, we do ``len(greeting)`` whose result is 6. + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +"Life is like riding a bicycle. To keep your balance, you must keep moving". - Einstein \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_1_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_1_en.rst.txt new file mode 100644 index 0000000000..000e4795fc --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_1_en.rst.txt @@ -0,0 +1,20 @@ +First program +================= + +.. code-block:: python + + >>> print("hello world!") + hello world! + ++ This program has only one line of code ++ Note that the quotes do not appear in the output ++ We need to mark or delimit the beginning and end of our messages with a symbol, in this case, quotes + +**Now try it on your own!** + ++ Type ``print("first message")`` in the interpreter below and check that you receive the output of your message without quotes. + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_2.rst.txt b/293/_sources/lectures/TWP05/TWP05_2.rst.txt new file mode 100644 index 0000000000..8df76aca49 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_2.rst.txt @@ -0,0 +1,76 @@ +Primer mensaje de error +========================= + ++ Las letras mayúsculas y minúsculas son diferentes ++ ``print()`` es diferente de ``Print()`` + +.. code-block:: python + + >>> Print ("¡hola mundo!") + Traceback (most recent call last): + File "", line 1, in + NameError: name 'Print' is not defined + +**¡Ahora inténtelo por su propia cuenta!** + +.. raw:: html + :file: ../_static/interpreter.html + + ++ Si no usamos comillas, la computadora interpretará nuestro mensaje + como un comando de Python, generando un error de sintaxis ++ ``"hola mundo"`` es diferente de ``hola mundo`` + +.. code-block:: python + + >>> print (hola mundo) + File "", line 1 + print (hola mundo) + ^ + SyntaxError: invalid syntax + +**¡Ahora inténtelo por su propia cuenta!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + ++ En la versión de Python que usamos (Python 3), los paréntesis no son opcionales al usar ``print()`` ++ ``print("hola mundo")`` es diferente de ``print "hola mundo"`` + +.. code-block:: python + + >>> print "hola mundo" + File "", line 1 + print "hola mundo" + ^ + SyntaxError: missing parenthesis in call to 'print' + +**¡Ahora inténtelo por su propia cuenta!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + ++ Los espacios iniciales tienen un significado en Python que veremos + más adelante, en este caso genera nuevamente un error de sintaxis ++ Estos espacios se llaman indentaciones o sangrías + +.. code-block:: python + + >>> print("primer mensaje!") + File "", line 1 + print "hola mundo" + ^ + SyntaxError: unexpected indent + +**¡Ahora inténtelo por su propia cuenta!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html diff --git a/293/_sources/lectures/TWP05/TWP05_2_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_2_en.rst.txt new file mode 100644 index 0000000000..11d68803ac --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_2_en.rst.txt @@ -0,0 +1,75 @@ +First error message +========================= + ++ Uppercase and lowercase letters are different ++ ``print()`` is different from ``Print()`` + +.. code-block:: python + + >>> Print ("hello world!") + Traceback (most recent call last): + File "", line 1, in + NameError: name 'Print' is not defined + +**Now try it on your own!** + +.. raw:: html + :file: ../_static/interpreter.html + + ++ If we don't use quotation marks, the computer will interpret our message + as a Python command, generating a syntax error ++ ``"hello world"`` is different from ``hello world`` + +.. code-block:: python + + >>> print (hello world) + File "", line 1 + print (hello world) + ^ + SyntaxError: invalid syntax + +**Now try it on your own!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + ++ In the Python version we're using (Python 3), parentheses are not optional when using ``print()`` ++ ``print("hello world")`` is different from ``print "hello world"`` + +.. code-block:: python + + >>> print "hello world" + File "", line 1 + print "hello world" + ^ + SyntaxError: missing parenthesis in call to 'print' + +**Now try it on your own!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + ++ Initial spaces have a meaning in Python that we'll see later on, in this case it generates a syntax error again ++ These spaces are called indentations + +.. code-block:: python + + >>> print("first message!") + File "", line 1 + print "hello world" + ^ + SyntaxError: unexpected indent + +**Now try it on your own!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_3.rst.txt b/293/_sources/lectures/TWP05/TWP05_3.rst.txt new file mode 100644 index 0000000000..78f3d7eaf4 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_3.rst.txt @@ -0,0 +1,71 @@ +Modo interactivo y modo edición +=============================== + +Intérprete de Python +-------------------- + ++ El intérprete es un programa que acepta comandos escritos en Python + y los ejecuta línea por línea ++ El intérprete verifica que hayamos escrito el programa correctamente, + mostrando mensajes de error si hay un problema ++ Hay dos modos del intérprete de Python: modo interactivo y modo edición ++ En los ejemplos anteriores usamos el modo interactivo ++ Una ventaja del modo interactivo es poder probar los comandos y obtener + la respuesta al instante + + +Calculadora en el intérprete +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + >>> 2+3 # No te olvides de dar enter + 5 + >>> 5-3 + 2 + >>> 10-4+2 + 8 + >>> 2*10 # Asterisco para la multiplicación + 20 + >>> 10/4 # Barra inclinada para la división + 2.5 + >>> 2**3 # Exponenciación + 8 + >>> 10%3 # Residuo de la división (módulo) + 1 + >>> 16%7 + 2 + +**¡Ahora inténtelo por su propia cuenta!** +Escriba estas operaciones en el intérprete y use el modo interactivo como una calculadora + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + +Modo de edición +--------------- + +.. activecode:: ac_l05_3 + :nocodelens: + + Intente dar un enter dentro del bloque en modo de edición. + Note que no sucede nada al escribir enter al final de la línea. + En modo de edición es necesario "ejecutar" el programa (Para esto presione el botón de Run). + + ~~~~ + print("primer mensaje") + +Precauciones al escribir programas +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++ Las letras mayúsculas y minúsculas son diferentes ++ Las comillas son muy importantes y no deben pasarse por alto. Cada vez + que abres comillas, no olvides cerrarlas ++ Los paréntesis no son opcionales en Python. Cada paréntesis abierto debe + estar cerrado ++ Los espacios son muy importantes. El lenguaje Python se basa en + cantidad de espacios en blanco antes del comienzo de cada línea para + realizar diferentes operaciones. Esto se le conoce como indentación. diff --git a/293/_sources/lectures/TWP05/TWP05_3_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_3_en.rst.txt new file mode 100644 index 0000000000..f3168a294b --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_3_en.rst.txt @@ -0,0 +1,64 @@ +Interactive Mode and Editing Mode +================================= + +Python interpreter +------------------ + ++ The interpreter is a program that accepts commands written in Python and executes them line by line ++ The interpreter verifies that we have written the program correctly, displaying error messages if there is a problem ++ There are two modes in the Python interpreter: interactive mode and editing mode ++ In the previous examples, we used interactive mode ++ An advantage of interactive mode is being able to test commands and get an instant response + + +Calculator in the interpreter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + >>> 2+3 # Don't forget to press enter + 5 + >>> 5-3 + 2 + >>> 10-4+2 + 8 + >>> 2*10 # Asterisk for multiplication + 20 + >>> 10/4 # Slashed line for division + 2.5 + >>> 2**3 # Exponentiation + 8 + >>> 10%3 # Modulus (remainder of division) + 1 + >>> 16%7 + 2 + +**Now try it for yourself!** +Write these operations in the interpreter and use interactive mode as a calculator + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + +Editing Mode +------------ + +.. activecode:: ac_l05_3_en + :nocodelens: + + Try pressing enter inside the editing block. + Note that nothing happens when you press enter at the end of the line. + In editing mode, it is necessary to "execute" the program (To do this, press the Run button). + + ~~~~ + print("first message") + +Precautions when writing programs +--------------------------------- + ++ Upper case and lower case letters are different ++ Quotes are very important and should not be overlooked. Every time you open quotes, don't forget to close them ++ Parentheses are not optional in Python. Every open parenthesis must be closed ++ Spaces are very important. The Python language is based on the amount of white space before the beginning of each line to perform different operations. This is known as indentation. \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_4.rst.txt b/293/_sources/lectures/TWP05/TWP05_4.rst.txt new file mode 100644 index 0000000000..64c4b58b9e --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_4.rst.txt @@ -0,0 +1,45 @@ +Conceptos sobre variables y asignación +====================================== + ++ Las variables se utilizan para almacenar valores y nombrar + un área de la memoria de la computadora ++ El símbolo para la asignación es el igual (``=``) + +.. codelens:: cl_l05_4a + + a = 2 + b = 3 + print(a + b) + ++ Como en matemáticas, pasamos parámetros o valores para una función usando paréntesis ++ Una función ``f(x)``, donde ``f`` es el nombre de la función y ``x`` es un parámetro ++ En el ejemplo anterior, ``print`` es el nombre de la función y ``a + b`` el valor pasado como parámetro ++ También podemos usar el modo interactivo **¡Pruebelo aquí!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + ++ Las dos primeras líneas no envían nada a la pantalla, así que solo se muestra el resultado de la tercera línea + +Otras alternativas +****************** + ++ Quizás se pregunte ¿por qué creamos dos variables, ``a`` y + ``b``, para sumar dos números? ++ Podríamos haber logrado el mismo resultado de varias maneras. + +.. codelens:: cl_l05_4b + + print(2 + 3) + print(5) + ++ ¿Cuál es la diferencia entre el primer modo y los dos últimos? ++ El primer caso incluye la lógica que usamos para obtener el + resultado ++ De este modo, hacemos explícito el algoritmo que utilizamos mentalmente para + resolver este problema ++ En los últimos dos casos, solo ordenamos a la computadora que imprima + algo concreto, sin dejar en claro la lógica para llegar a ese resultado diff --git a/293/_sources/lectures/TWP05/TWP05_4_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_4_en.rst.txt new file mode 100644 index 0000000000..bdf7383e6c --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_4_en.rst.txt @@ -0,0 +1,40 @@ +Concepts about variables and assignment +======================================= + ++ Variables are used to store values ​​and name an area of ​​the computer's memory ++ The symbol for assignment is the equals sign (``=``) + +.. codelens:: cl_l05_4a_en + + a = 2 + b = 3 + print(a + b) + ++ Like in mathematics, we pass parameters or values ​​to a function using parentheses ++ A function ``f(x)``, where ``f`` is the name of the function and ``x`` is a parameter ++ In the previous example, ``print`` is the name of the function and ``a + b`` is the value passed as a parameter ++ We can also use the interactive mode **Try it here!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + + ++ The first two lines do not print anything to the screen, so only the result of the third line is shown + +Other alternatives +****************** + ++ You may wonder why we create two variables, ``a`` and ``b``, to add two numbers? ++ We could have achieved the same result in several ways. + +.. codelens:: cl_l05_4b_en + + print(2 + 3) + print(5) + ++ What is the difference between the first way and the last two? ++ The first case includes the logic we used to obtain the result ++ This way, we explicitly state the algorithm we used mentally to solve this problem ++ In the last two cases, we simply command the computer to print something specific, without making clear the logic to arrive at that result. \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_5.rst.txt b/293/_sources/lectures/TWP05/TWP05_5.rst.txt new file mode 100644 index 0000000000..c46c638598 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_5.rst.txt @@ -0,0 +1,34 @@ +Nombres de variables +==================== + ++ En Python, los nombres de las variables deben comenzar con un + letra o guión bajo ``_`` ++ ¡Acentos están permitidos! ++ Ejemplo de nombres válidos: ``precio``, ``acción``, ``salario``, ``_x``, + ``año_2011``, ``salario_promedio`` + +.. code-block:: python + + >>> a = 2 + >>> precio = 500 + >>> print(a) + 2 + >>> print(precio) + 500 + ++ Ejemplo de nombres no válidos: ``salario promedio``, ``3x``, ``1er``, ``@``, ``$`` + +.. code-block:: python + + >>> 3x = "texto" + File "", line 1 + 3x = "texto" + ^ + SyntaxError: invalid syntax + +**Defina variables válidas e invalidas a continuación** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html diff --git a/293/_sources/lectures/TWP05/TWP05_5_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_5_en.rst.txt new file mode 100644 index 0000000000..6b082beec3 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_5_en.rst.txt @@ -0,0 +1,33 @@ +Variable names +============== + ++ In Python, variable names must start with a letter or underscore ``_`` ++ Accents are allowed! ++ Examples of valid names: ``price``, ``action``, ``salary``, ``_x``, + ``year_2011``, ``average_salary`` + +.. code-block:: python + + >>> a = 2 + >>> price = 500 + >>> print(a) + 2 + >>> print(price) + 500 + ++ Examples of invalid names: ``average salary``, ``3x``, ``1st``, ``@``, ``$`` + +.. code-block:: python + + >>> 3x = "text" + File "", line 1 + 3x = "text" + ^ + SyntaxError: invalid syntax + +**Define valid and invalid variables below** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_6.rst.txt b/293/_sources/lectures/TWP05/TWP05_6.rst.txt new file mode 100644 index 0000000000..0855ed2ed6 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_6.rst.txt @@ -0,0 +1,15 @@ +Tipos de variables +================== + +.. image:: ../img/TWP05_015.png + :height: 8.507cm + :width: 16.595cm + :align: center + :alt: + ++ El contenido de una variable tiene un tipo ++ El tipo define la naturaleza de los datos que almacena la variable ++ Los tipos más comunes son: + + **Numéricas:** numeros enteros, números de coma flotante. + + **Cadenas o texto:** poder almacenar números, letras y otros caracteres. + + **Lógicas:** almacenan valores como Verdadero y Falso. diff --git a/293/_sources/lectures/TWP05/TWP05_6_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_6_en.rst.txt new file mode 100644 index 0000000000..cd7f26c078 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_6_en.rst.txt @@ -0,0 +1,15 @@ +Variable types +============== + +.. image:: ../img/TWP05_015.png + :height: 8.507cm + :width: 16.595cm + :align: center + :alt: + ++ The content of a variable has a type. ++ The type defines the nature of the data that the variable stores. ++ The most common types are: + + **Numeric types:** integers, floating point numbers. + + **Strings or text:** can store numbers, letters and other characters. + + **Boolean types:** store values as True and False. \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_7.rst.txt b/293/_sources/lectures/TWP05/TWP05_7.rst.txt new file mode 100644 index 0000000000..daa1449df1 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_7.rst.txt @@ -0,0 +1,28 @@ +Variables numéricas +=================== + ++ Los enteros no tienen decimales: ``42``, ``-7`` ++ Los valores del tipo entero en Python se llaman ``int`` ++ Los números en coma flotante tienen decimales: ``1.0``, ``3.1415``, + ``1234.56`` ++ Tenga en cuenta que ``1.0``, incluso teniendo cero en la parte decimal, es un número en + punto flotante ++ Los valores de tipo coma flotante en Python se llaman ``float``. + + +Representación de valores numéricos +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++ Internamente todos los números son representados con el + sistema binario ++ Este sistema permite solo los dígitos ``0`` o ``1`` ++ Los números en punto flotante pueden no tener una correcta representación + en el sistema binario ++ Tecleando en el intérprete ``3 * 0.1`` tendremos como respuesta: ``0.30000000000000004`` + +**¡Pruebelo aquí!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html diff --git a/293/_sources/lectures/TWP05/TWP05_7_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_7_en.rst.txt new file mode 100644 index 0000000000..6b92b6ef39 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_7_en.rst.txt @@ -0,0 +1,27 @@ +Numeric variables +=================== + ++ Integers do not have decimal places: ``42``, ``-7`` ++ Values of type integer in Python are called ``int`` ++ Floating point numbers have decimal places: ``1.0``, ``3.1415``, + ``1234.56`` ++ Note that ``1.0``, even though it has a zero in the decimal part, is a floating point number ++ Values of type floating point in Python are called ``float``. + + +Representation of numeric values +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++ Internally, all numbers are represented with the binary system ++ This system only allows the digits ``0`` or ``1`` ++ Floating point numbers may not have a proper representation + in the binary system ++ Typing in the interpreter ``3 * 0.1`` will give us a response of: ``0.30000000000000004`` + +**Try it here!** + +.. only:: html + + .. raw:: html + :file: ../_static/interpreter.html + diff --git a/293/_sources/lectures/TWP05/TWP05_8.rst.txt b/293/_sources/lectures/TWP05/TWP05_8.rst.txt new file mode 100644 index 0000000000..b01c41dde9 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_8.rst.txt @@ -0,0 +1,68 @@ +Variables lógicas +================= + ++ Podemos almacenar verdadero y falso ++ Las variables de este tipo se llaman lógicas o booleanas ++ En Python podemos inicializar variables de este tipo con ``True`` o ``False`` ++ Tenga en cuenta que la T y la F están en mayúsculas, cualquier otra forma genera + un error de sintaxis + +Operadores relacionales +----------------------- + +.. table:: **Operadores relacionales** + :widths: auto + + ======== ============== ============================== + Operador Operación Símbolo matemático equivalente + ======== ============== ============================== + == igual = + > mayor que > + < menor que < + != diferente <> + >= mayor o igual >= + <= menor o igual <= + ======== ============== ============================== + ++ Tenga en cuenta que el operador de igualdad son dos iguales (``==``) + +Ejemplos: +--------- + +.. codelens:: cl_l05_8a + + a = 1 + b = 5 + c = 2 + d = 1 + print(a == b) + print(b > a) + print(a < b) + print(a == d) + print(b >= a) + print(c <= b) + print(d != a) + print(d != b) + +Ejemplo importante +------------------ + ++ >= o <= para valores iguales + +.. codelens:: cl_l05_8b + + print(5 >= 5) + print(5 <= 5) + +Ejemplo +------- + ++ Podemos usar operadores relacionales para inicializar variables del + tipo lógico + +.. codelens:: cl_l05_8c + + nota = 8 + promedio = 6 + aprobado = nota > promedio + print(aprobado) diff --git a/293/_sources/lectures/TWP05/TWP05_8_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_8_en.rst.txt new file mode 100644 index 0000000000..2914f80767 --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_8_en.rst.txt @@ -0,0 +1,66 @@ +Boolean Variables +================= + ++ We can store true and false ++ Variables of this type are called logical or boolean ++ In Python, we can initialize variables of this type with ``True`` or ``False`` ++ Note that the T and F are capitalized, any other form generates a syntax error + +Relational Operators +----------------------- + +.. table:: **Relational Operators** + :widths: auto + + ======== ================ ============================== + Operator Operation Mathematical equivalent symbol + ======== ================ ============================== + == equal = + > greater than > + < less than < + != not equal <> + >= greater or equal >= + <= less or equal <= + ======== ================ ============================== + ++ Note that the equality operator is two equals (``==``) + +Examples: +--------- + +.. codelens:: cl_l05_8a_en + + a = 1 + b = 5 + c = 2 + d = 1 + print(a == b) + print(b > a) + print(a < b) + print(a == d) + print(b >= a) + print(c <= b) + print(d != a) + print(d != b) + +Important Example +------------------ + ++ >= or <= for equal values + +.. codelens:: cl_l05_8b_en + + print(5 >= 5) + print(5 <= 5) + +Example +------- + ++ We can use relational operators to initialize logical variables + +.. codelens:: cl_l05_8c_en + + grade = 8 + average = 6 + passed = grade > average + print(passed) \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/TWP05_9.rst.txt b/293/_sources/lectures/TWP05/TWP05_9.rst.txt new file mode 100644 index 0000000000..f93d7b66db --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_9.rst.txt @@ -0,0 +1,33 @@ +Operadores lógicos +================== + ++ Tenemos tres operadores básicos: ``not``, ``and`` y ``or`` + +Uso del operador ``not`` +************************ + +.. codelens:: cl_l05_9a + + print(not True) + print(not False) + +Uso del operador ``and`` +************************ + +.. codelens:: cl_l05_9b + + print(True and True) + print(True and False) + print(False and True) + print(False and False) + +Uso del operador ``or`` +************************ + +.. codelens:: cl_l05_9c + + print(True or True) + print(True or False) + print(False or True) + print(False or False) + diff --git a/293/_sources/lectures/TWP05/TWP05_9_en.rst.txt b/293/_sources/lectures/TWP05/TWP05_9_en.rst.txt new file mode 100644 index 0000000000..317c59c54a --- /dev/null +++ b/293/_sources/lectures/TWP05/TWP05_9_en.rst.txt @@ -0,0 +1,32 @@ +Logical Operators +----------------- + ++ We have three basic operators: ``not``, ``and``, and ``or``. + +Using the ``not`` operator +************************** + +.. codelens:: cl_l05_9a_en + + print(not True) + print(not False) + +Using the ``and`` operator +************************** + +.. codelens:: cl_l05_9b_en + + print(True and True) + print(True and False) + print(False and True) + print(False and False) + +Using the ``or`` operator +************************* + +.. codelens:: cl_l05_9c_en + + print(True or True) + print(True or False) + print(False or True) + print(False or False) \ No newline at end of file diff --git a/293/_sources/lectures/TWP05/toctree.rst.txt b/293/_sources/lectures/TWP05/toctree.rst.txt new file mode 100644 index 0000000000..de0811acbe --- /dev/null +++ b/293/_sources/lectures/TWP05/toctree.rst.txt @@ -0,0 +1,33 @@ +============================ +Variables y entrada de datos +============================ + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.832cm + :width: 9.2cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP05_1.rst + TWP05_2.rst + TWP05_3.rst + TWP05_4.rst + TWP05_5.rst + TWP05_6.rst + TWP05_7.rst + TWP05_8.rst + TWP05_9.rst + TWP05_10.rst + TWP05_11.rst + TWP05_12.rst + TWP05_13.rst + TWP05_14.rst + TWP05_15.rst + TWP05_16.rst diff --git a/293/_sources/lectures/TWP05/toctree_en.rst.txt b/293/_sources/lectures/TWP05/toctree_en.rst.txt new file mode 100644 index 0000000000..2e8e74befb --- /dev/null +++ b/293/_sources/lectures/TWP05/toctree_en.rst.txt @@ -0,0 +1,33 @@ +============================ +Variables and Input of Data +============================ + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.832cm + :width: 9.2cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP05_1_en.rst + TWP05_2_en.rst + TWP05_3_en.rst + TWP05_4_en.rst + TWP05_5_en.rst + TWP05_6_en.rst + TWP05_7_en.rst + TWP05_8_en.rst + TWP05_9_en.rst + TWP05_10_en.rst + TWP05_11_en.rst + TWP05_12_en.rst + TWP05_13_en.rst + TWP05_14_en.rst + TWP05_15_en.rst + TWP05_16_en.rst diff --git a/293/_sources/lectures/TWP10/TWP10_1.rst.txt b/293/_sources/lectures/TWP10/TWP10_1.rst.txt new file mode 100644 index 0000000000..b6a1d02394 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_1.rst.txt @@ -0,0 +1,15 @@ +Condiciones +=========== + +.. codelens:: cl_l10_1 + + print("¡Bienvenido a mi programa!") + print("¡Vuelva siempre!") + +.. image:: ../img/TWP10_002.jpg + :height: 5.524cm + :width: 22.859cm + :align: center + :alt: + ++ Tus programas no siempre serán simples secuencias de comandos diff --git a/293/_sources/lectures/TWP10/TWP10_1_en.rst.txt b/293/_sources/lectures/TWP10/TWP10_1_en.rst.txt new file mode 100644 index 0000000000..8820d8e92d --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_1_en.rst.txt @@ -0,0 +1,15 @@ +Conditions +========== + +.. codelens:: cl_l10_1_en + + print("Welcome to my program!") + print("Come back always!") + +.. image:: ../img/TWP10_002.jpg + :height: 5.524cm + :width: 22.859cm + :align: center + :alt: + ++ Your programs may not always be simple scripts. \ No newline at end of file diff --git a/293/_sources/lectures/TWP10/TWP10_2.rst.txt b/293/_sources/lectures/TWP10/TWP10_2.rst.txt new file mode 100644 index 0000000000..86b6cdb63f --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_2.rst.txt @@ -0,0 +1,12 @@ +“¿Correr o no correr? Esa es la cuestión..." +============================================ + ++ En general no ejecuto todas las líneas del programa. ++ Ir a través de las líneas de un programa es como viajar en automóvil en una ciudad. ++ Hay puntos dónde decidimos qué camino elegir. + +.. image:: ../img/TWP10_004.png + :height: 13.389cm + :width: 20.001cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP10/TWP10_2_en.rst.txt b/293/_sources/lectures/TWP10/TWP10_2_en.rst.txt new file mode 100644 index 0000000000..29106cfda4 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_2_en.rst.txt @@ -0,0 +1,12 @@ +"Run or not to run? That is the question... +============================================ + ++ In general, I don't execute all the lines of the program. ++ Going through the lines of a program is like driving a car in a city. ++ There are points where we decide which path to choose. + +.. image:: ../img/TWP10_004.png + :height: 13.389cm + :width: 20.001cm + :align: center + :alt: Python code snippet. \ No newline at end of file diff --git a/293/_sources/lectures/TWP10/TWP10_3.rst.txt b/293/_sources/lectures/TWP10/TWP10_3.rst.txt new file mode 100644 index 0000000000..db44ee7866 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_3.rst.txt @@ -0,0 +1,44 @@ +``if`` +====== + ++ Lea dos valores enteros e imprima el más grande + +.. codelens:: cl_l10_3a + + a = 8 + b = 5 + if a > b: + print("El primer número es el más grande") + if b > a: + print("¡El segundo número es el más grande!") + + +Dos puntos e identación +*********************** + ++ Note que en Python es obligatorio culminar cualquier condición (if) con ``:``. ++ Recuerda también identar los bloques de código dentro de las condiciones, es obligatorio. + + +Verificar si un auto es nuevo o viejo: ++ Si el auto tiene al menos tres años de creado, es nuevo, es viejo en caso contrario. + +.. codelens:: cl_l10_3b + + anio_creacion = 10 + if anio_creacion <= 3: + print("Su auto es nuevo") + if anio_creacion > 3: + print("Su auto es viejo") + ++ Pregunte la velocidad de un automóvil, suponiendo que es un número entero. ++ En caso de que la velocidad supere los 110 km/h, muestre un mensaje que dice que el usuario ha sido multado. ++ Muestre el monto de la multa si es multado, cobrando ``$5.00`` por cada km por encima de los 110 km/h. + +.. codelens:: cl_l10_3c + + velocidad = 120 + if velocidad > 110: + print("Usted a sido multado") + multa = (velocidad - 110) * 5 + print("Valor de la multa : $%5.2f " % multa) diff --git a/293/_sources/lectures/TWP10/TWP10_3_en.rst.txt b/293/_sources/lectures/TWP10/TWP10_3_en.rst.txt new file mode 100644 index 0000000000..4a1bdb2f42 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_3_en.rst.txt @@ -0,0 +1,44 @@ +``if`` +====== + ++ Read two integer values and print the larger one + +.. codelens:: cl_l10_3a_en + + a = 8 + b = 5 + if a > b: + print("The first number is the largest!") + if b > a: + print("The second number is the biggest!") + + +Two points and indentation +************************** + ++ Note that in Python it is mandatory to complete any condition (if) with ``:``. ++ Also remember to indent the code blocks inside the conditions, it is mandatory. + + +Check if a car is new or old: ++ If the car is at least three years old, it's new, it is old otherwise. + +.. codelens:: cl_l10_3b_en + + years_old = 10 + if years_old <= 3: + print("his car is new") + if years_old > 3: + print("his car is old") + ++ Ask the speed of a car, assuming it is an integer. ++ In case the speed exceeds 110 km/h, display a message saying that the user has been fined. ++ Show the amount of the fine if you are fined, charging ``$5.00`` for each km above the 110 km/h. + +.. codelens:: cl_l10_3c_en + + speed = 120 + if speed > 110: + print("you have been fined") + fine = (speed - 110) * 5 + print("Value of the fine : $%5.2f " % fine) diff --git a/293/_sources/lectures/TWP10/TWP10_4.rst.txt b/293/_sources/lectures/TWP10/TWP10_4.rst.txt new file mode 100644 index 0000000000..0503d91817 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_4.rst.txt @@ -0,0 +1,32 @@ +``if`` / ``else`` +================= + ++ ¿Qué hacer cuando la condición ``if`` es falsa?. ++ La clausula ``else`` significa en caso contrario. ++ Se suele usar cuando para indicar condiciones complementarias. ++ Las condiciones if / else pueden verse como un carro al llegar a una bifurcación en la ruta. ++ Dependiendo del resultado de una condición el carro puede ir por la ruta de arriba o por la ruta de abajo. + +.. image:: ../img/TWP10_009.jpg + :height: 9.754cm + :width: 22.859cm + :align: center + :alt: + ++ Los dos códigos a continuación hacen lo mismo pero uno usando condiciones if / else + +.. codelens:: cl_l10_4a + + anio_creacion = 1 + if anio_creacion <= 3: + print("Su auto es nuevo") + if anio_creacion > 3: + print("Su auto es viejo") + +.. codelens:: cl_l10_4b + + anio_creacion = 1 + if anio_creacion <= 3: + print("Su auto es nuevo") + else: + print("Su auto es viejo") diff --git a/293/_sources/lectures/TWP10/TWP10_4_en.rst.txt b/293/_sources/lectures/TWP10/TWP10_4_en.rst.txt new file mode 100644 index 0000000000..a9d4b989aa --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_4_en.rst.txt @@ -0,0 +1,32 @@ +``if`` / ``else`` +================= + ++ What to do when the ``if`` condition is false?. ++ The ``else`` clause means otherwise. ++ It is usually used to indicate complementary conditions. ++ The if / else conditions can be seen as a car arriving at a fork in the road. ++ Depending on the result of a condition, the car can take the upper or lower road. + +.. image:: ../img/TWP10_009.jpg + :height: 9.754cm + :width: 22.859cm + :align: center + :alt: + ++ The two codes below do the same thing but one uses if / else conditions. + +.. codelens:: cl_l10_4a_en + + creation_year = 1 + if creation_year <= 3: + print("Your car is new") + if creation_year > 3: + print("Your car is old") + +.. codelens:: cl_l10_4b_en + + creation_year = 1 + if creation_year <= 3: + print("Your car is new") + else: + print("Your car is old") \ No newline at end of file diff --git a/293/_sources/lectures/TWP10/TWP10_5.rst.txt b/293/_sources/lectures/TWP10/TWP10_5.rst.txt new file mode 100644 index 0000000000..b6df13e79b --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_5.rst.txt @@ -0,0 +1,48 @@ +Estructuras anidadas +==================== + ++ Considere la compañía telefónica "Chao". Por debajo de 200 minutos, la empresa cobra ``$0.20`` por minuto. Entre 200 y 400 minutos, el precio es de ``$0.18``. Por encima de 400 minutos, el precio por minuto es de ``$0.15``. Calcular tu factura de teléfono con estas condiciones. ++ Las condiciones de la compañía, puede verse representado visualmente con la ruta de una carretera como la siguiente imagen. + +.. image:: ../img/TWP10_011.jpg + :height: 9.754cm + :width: 22.859cm + :align: center + :alt: + ++ Pueden crearse condiciones anidadas. ++ Recuerda identar las porciones de código que se encuentren anidadas. + +.. codelens:: cl_l10_5a + + minutos = 800 + if minutos < 200: + precio = 0.20 + else: + if minutos <= 400: + precio = 0.18 + else: + precio = 0.15 + print("Cuenta telefonica : $%6.2f" % (minutos * precio)) + ++ Note la doble identación para cumplir la segunda condición. ++ Ahora modificamos el programa de la compañía "Chao" para una promoción dónde la tarifa es de ``$0.08`` cuando usa más de 800 minutos. + +.. codelens:: cl_l10_5b + + minutos = 1000 + if minutos < 200: + precio = 0.2 + else: + if minutos <= 400: + precio = 0.18 + else: + if minutos <= 800: + precio = 0.15 + else: + precio = 0.08 + print("Cuenta telefonica : $%6.2f" % (minutos * precio)) + ++ Note que las estructuras anidadas pueden crecer. ++ Python dada sus características proporciona la clausula ``elif``. ++ Se utiliza para verificar múltiples condiciones. diff --git a/293/_sources/lectures/TWP10/TWP10_5_en.rst.txt b/293/_sources/lectures/TWP10/TWP10_5_en.rst.txt new file mode 100644 index 0000000000..c336d58a78 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_5_en.rst.txt @@ -0,0 +1,48 @@ +Nested Structures +==================== + ++ Consider the telephone company "Chao". Below 200 minutes, the company charges ``$0.20`` per minute. Between 200 and 400 minutes, the price is ``$0.18``. Above 400 minutes, the price per minute is ``$0.15``. Calculate your phone bill with these conditions. ++ The company's conditions can be visually represented by the path of a road like the following image. + +.. image:: ../img/TWP10_011.jpg + :height: 9.754cm + :width: 22.859cm + :align: center + :alt: + ++ Nested conditions can be created. ++ Remember to indent nested portions of code. + +.. codelens:: cl_l10_5a_en + + minutes = 800 + if minutes < 200: + price = 0.20 + else: + if minutes <= 400: + price = 0.18 + else: + price = 0.15 + print("Telephone bill : $%6.2f" % (minutes * price)) + ++ Note the double indentation to satisfy the second condition. ++ Now we modify the "Chao" company program for a promotion where the rate is ``$0.08`` when you use more than 800 minutes. + +.. codelens:: cl_l10_5b_en + + minutes = 1000 + if minutes < 200: + price = 0.2 + else: + if minutes <= 400: + price = 0.18 + else: + if minutes <= 800: + price = 0.15 + else: + price = 0.08 + print("Telephone bill : $%6.2f" % (minutes * price)) + ++ Note that nested structures can grow. ++ Python, given its characteristics, provides the "elif" clause. ++ It is used to check multiple conditions. \ No newline at end of file diff --git a/293/_sources/lectures/TWP10/TWP10_6.rst.txt b/293/_sources/lectures/TWP10/TWP10_6.rst.txt new file mode 100644 index 0000000000..dd309dec64 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_6.rst.txt @@ -0,0 +1,17 @@ +``elif`` +======== + ++ La cláusula elif sustituye a ``else`` y ``if``. + +.. codelens:: cl_l10_6 + + minutos = 1000 + if minutos < 200: + precio = 0.2 + elif minutos <= 400: + precio = 0.18 + elif minutos <= 800: + precio = 0.15 + else: + precio = 0.08 + print("Cuenta telefonica : $%6.2f" % (minutos * precio)) diff --git a/293/_sources/lectures/TWP10/TWP10_6_en.rst.txt b/293/_sources/lectures/TWP10/TWP10_6_en.rst.txt new file mode 100644 index 0000000000..7b00a1feaf --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_6_en.rst.txt @@ -0,0 +1,17 @@ +``elif`` +======== + ++ The ``elif`` clause replaces both ``else`` and ``if``. + +.. codelens:: cl_l10_6_en + + minutes = 1000 + if minutes < 200: + price = 0.2 + elif minutes <= 400: + price = 0.18 + elif minutes <= 800: + price = 0.15 + else: + price = 0.08 + print("Phone bill: $%6.2f" % (minutes * price)) \ No newline at end of file diff --git a/293/_sources/lectures/TWP10/TWP10_7.rst.txt b/293/_sources/lectures/TWP10/TWP10_7.rst.txt new file mode 100644 index 0000000000..9030c2c6d3 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_7.rst.txt @@ -0,0 +1,79 @@ +Lista de Ejercicios “again” +=========================== + ++ Condiciones + +.. activecode:: ac_l10_7_001 + :nocodelens: + :stdin: + + print("¡Bienvenido a mi programa!") + print("¡Vuelva siempre!") + ++ Condiciones -- if + +.. activecode:: ac_l10_7_002 + :nocodelens: + :stdin: + + a = 8 + b = 5 + if a > b: + print("El primer número es el más grande") + if b > a: + print("¡El segundo número es el más grande!") + + ++ Condiciones -- if / else + +.. activecode:: ac_l10_7_003 + :nocodelens: + :stdin: + + anio_creacion = 1 + if anio_creacion <= 3: + print("Su auto es nuevo") + if anio_creacion > 3: + print("Su auto es viejo") + + ++ Estructuras anidadas + +.. activecode:: ac_l10_7_004 + :nocodelens: + :stdin: + + minutos = 800 + if minutos < 200: + precio = 0.20 + else: + if minutos <= 400: + precio = 0.18 + else: + precio = 0.15 + print("Cuenta telefonica : $%6.2f" % (minutos * precio)) + ++ elif + +.. activecode:: ac_l10_7_005 + :nocodelens: + :stdin: + + minutos = 1000 + if minutos < 200: + precio = 0.2 + elif minutos <= 400: + precio = 0.18 + elif minutos <= 800: + precio = 0.15 + else: + precio = 0.08 + print("Cuenta telefonica : $%6.2f" % (minutos * precio)) + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +“La vida es como andar en bicicleta. Para mantener el equilibrio, debes seguir moviéndote”. - Einstein \ No newline at end of file diff --git a/293/_sources/lectures/TWP10/TWP10_7_en.rst.txt b/293/_sources/lectures/TWP10/TWP10_7_en.rst.txt new file mode 100644 index 0000000000..039a44e110 --- /dev/null +++ b/293/_sources/lectures/TWP10/TWP10_7_en.rst.txt @@ -0,0 +1,81 @@ +Exercise List “again” +=========================== + ++ Conditions + +.. activecode:: ac_l10_7_001_en + :nocodelens: + :stdin: + + print("Welcome to my program!") + print("Always come back!") + ++ Conditions -- if + + +.. activecode:: ac_l10_7_002_en + :nocodelens: + :stdin: + + a = 8 + b = 5 + if a > b: + print("The first number is the largest") + if b > a: + print("The second number is the biggest!") + + ++ Conditions -- if / else + + +.. activecode:: ac_l10_7_003_en + :nocodelens: + :stdin: + + years_old = 1 + if years_old <= 3: + print("his car is new") + if years_old > 3: + print("his car is old") + + ++ nested structures + +.. activecode:: ac_l10_7_004_en + :nocodelens: + :stdin: + + minutes = 800 + if minutes < 200: + price = 0.20 + else: + if minutes <= 400: + price = 0.18 + else: + price = 0.15 + print("phone account : $%6.2f" % (minutes * price)) + ++ elif + +.. activecode:: ac_l10_7_005_en + :nocodelens: + :stdin: + + minutes = 1000 + if minutes < 200: + price = 0.2 + elif minutes <= 400: + price = 0.18 + elif minutes <= 800: + price = 0.15 + else: + price = 0.08 + print("phone account : $%6.2f" % (minutes * price)) + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +“Life is like riding a bicycle. To keep balance, you must keep moving”. - Einstein diff --git a/293/_sources/lectures/TWP10/toctree.rst.txt b/293/_sources/lectures/TWP10/toctree.rst.txt new file mode 100644 index 0000000000..d4adeaff82 --- /dev/null +++ b/293/_sources/lectures/TWP10/toctree.rst.txt @@ -0,0 +1,24 @@ +=========== +Condiciones +=========== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP10_1.rst + TWP10_2.rst + TWP10_3.rst + TWP10_4.rst + TWP10_5.rst + TWP10_6.rst + TWP10_7.rst diff --git a/293/_sources/lectures/TWP10/toctree_en.rst.txt b/293/_sources/lectures/TWP10/toctree_en.rst.txt new file mode 100644 index 0000000000..7c7ece5ad2 --- /dev/null +++ b/293/_sources/lectures/TWP10/toctree_en.rst.txt @@ -0,0 +1,24 @@ +=========== +Conditions +=========== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP10_1_en.rst + TWP10_2_en.rst + TWP10_3_en.rst + TWP10_4_en.rst + TWP10_5_en.rst + TWP10_6_en.rst + TWP10_7_en.rst diff --git a/293/_sources/lectures/TWP15/TWP15_1.rst.txt b/293/_sources/lectures/TWP15/TWP15_1.rst.txt new file mode 100644 index 0000000000..f4d9c6551d --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_1.rst.txt @@ -0,0 +1,19 @@ +Repeticiones +============ + + +.. image:: ../img/TWP15_001.jpg + :height: 15.602cm + :width: 16.801cm + :align: center + :alt: + +.. raw:: html + +
+ +.. image:: ../img/TWP15_002.jpeg + :height: 19.049cm + :width: 12.668cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP15/TWP15_1_en.rst.txt b/293/_sources/lectures/TWP15/TWP15_1_en.rst.txt new file mode 100644 index 0000000000..d53b699852 --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_1_en.rst.txt @@ -0,0 +1,20 @@ +Repetitions +============ + + +.. image:: ../img/TWP15_001.jpg + :height: 15.602cm + :width: 16.801cm + :align: center + :alt: + +.. raw:: html + +
+ +.. image:: ../img/TWP15_002.jpeg + :height: 19.049cm + :width: 12.668cm + :align: center + :alt: + diff --git a/293/_sources/lectures/TWP15/TWP15_2.rst.txt b/293/_sources/lectures/TWP15/TWP15_2.rst.txt new file mode 100644 index 0000000000..9afa2b683f --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_2.rst.txt @@ -0,0 +1,86 @@ +Impresión de 1 a 3 +=================== + + +Forma simple +************* + +.. codelens:: cl_l15_2a + + print(1) + print(2) + print(3) + + +Usando una variable +******************* + +.. codelens:: cl_l15_2b + + x = 1 + print(x) + x = 2 + print(x) + x = 3 + print(x) + + +Incrementando la variable +************************* + +.. codelens:: cl_l15_2c + + x = 1 + print(x) + x = x + 1 + print(x) + x = x + 1 + print(x) + +Usando ``while`` +**************** + +.. codelens:: cl_l15_2d + + x = 1 + while x <= 3: + print(x) + x = x +1 + + +.. image:: ../img/TWP15_007.jpeg + :height: 14.804cm + :width: 22.181cm + :align: center + :alt: + + +Prueba de escritorio +-------------------- + +.. code-block:: python + + x = 1 + while x <= 3: + print(x) + x = x + 1 + +.. table:: **Prueba de escritorio** + :widths: auto + :align: left + + ====== ======== + x Pantalla + ====== ======== + -1- 1 + -2- 2 + -3- 3 + 4 + ====== ======== + +.. codelens:: cl_l15_2e + + x = 1 + while x <= 3: + print(x) + x = x + 1 diff --git a/293/_sources/lectures/TWP15/TWP15_2_en.rst.txt b/293/_sources/lectures/TWP15/TWP15_2_en.rst.txt new file mode 100644 index 0000000000..7178f58d4c --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_2_en.rst.txt @@ -0,0 +1,86 @@ +Printing from 1 to 3 +==================== + + +Simple way +********** + +.. codelens:: cl_l15_2a_en + + print(1) + print(2) + print(3) + + +Using a variable +***************** + +.. codelens:: cl_l15_2b_en + + x = 1 + print(x) + x = 2 + print(x) + x = 3 + print(x) + + +Incrementing the variable +************************** + +.. codelens:: cl_l15_2c_en + + x = 1 + print(x) + x = x + 1 + print(x) + x = x + 1 + print(x) + +Using ``while`` +**************** + +.. codelens:: cl_l15_2d_en + + x = 1 + while x <= 3: + print(x) + x = x +1 + + +.. image:: ../img/TWP15_007.jpeg + :height: 14.804cm + :width: 22.181cm + :align: center + :alt: + + +Desk checking +------------- + +.. code-block:: python + + x = 1 + while x <= 3: + print(x) + x = x + 1 + +.. table:: **Desk checking** + :widths: auto + :align: left + + ====== ======== + x Screen + ====== ======== + -1- 1 + -2- 2 + -3- 3 + 4 + ====== ======== + +.. codelens:: cl_l15_2e_en + + x = 1 + while x <= 3: + print(x) + x = x + 1 \ No newline at end of file diff --git a/293/_sources/lectures/TWP15/TWP15_3.rst.txt b/293/_sources/lectures/TWP15/TWP15_3.rst.txt new file mode 100644 index 0000000000..fc80272b6c --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_3.rst.txt @@ -0,0 +1,61 @@ +Contadores +========== + ++ Ahora imprima de 1 a un número ingresado por el usuario + +.. activecode:: ac_l15_3a + :nocodelens: + :stdin: + + fin = int(input("Ingrese el último número: ")) + x = 1 + while x <= fin: + print(x) + x = x + 1 + ++ Imprima números pares entre 0 y un número dado por el usuario usando ``if`` + +.. activecode:: ac_l15_3b + :nocodelens: + :stdin: + + fin = int(input("Ingrese el último número: ")) + x = 0 + while x <= fin: + if x%2 == 0: + print(x) + x = x + 1 + + ++ Imprima números pares entre 0 y un número proporcionado sin usar + ``if`` + +.. activecode:: ac_l15_3c + :nocodelens: + :stdin: + + fin = int(input("Ingrese el último número: ")) + x = 0 + while x <= fin: + print(x) + x = x + 2 + + +Algunos ejercicios +------------------ + +.. activecode:: ac_l15_3d + :nocodelens: + + Modifique el programa anterior para imprimir del 1 al número ingresado por el usuario, + pero esta vez solo los números impares. + + ~~~~ + + +.. activecode:: ac_l15_3e + :nocodelens: + + Escriba un programa que imprima los primeros 10 múltiplos de 3. + + ~~~~ diff --git a/293/_sources/lectures/TWP15/TWP15_3_en.rst.txt b/293/_sources/lectures/TWP15/TWP15_3_en.rst.txt new file mode 100644 index 0000000000..b4df73db6b --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_3_en.rst.txt @@ -0,0 +1,61 @@ +Counters +======== + ++ Now print from 1 to a number entered by the user + +.. activecode:: ac_l15_3a_en + :nocodelens: + :stdin: + + end = int(input("Enter the last number: ")) + x = 1 + while x <= end: + print(x) + x = x + 1 + ++ Print even numbers between 0 and a number given by the user using ``if`` + +.. activecode:: ac_l15_3b_en + :nocodelens: + :stdin: + + end = int(input("Enter the last number: ")) + x = 0 + while x <= end: + if x%2 == 0: + print(x) + x = x + 1 + + ++ Print even numbers between 0 and a provided number without using + ``if`` + +.. activecode:: ac_l15_3c_en + :nocodelens: + :stdin: + + end = int(input("Enter the last number: ")) + x = 0 + while x <= end: + print(x) + x = x + 2 + + +Some Exercises +-------------- + +.. activecode:: ac_l15_3d_en + :nocodelens: + + Modify the previous program to print from 1 to the number entered by + the user, but this time only the odd numbers. + + ~~~~ + + +.. activecode:: ac_l15_3e_en + :nocodelens: + + Write a program that prints the first 10 multiples of 3. + + ~~~~ \ No newline at end of file diff --git a/293/_sources/lectures/TWP15/TWP15_4.rst.txt b/293/_sources/lectures/TWP15/TWP15_4.rst.txt new file mode 100644 index 0000000000..b73b0ae755 --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_4.rst.txt @@ -0,0 +1,67 @@ +Acumuladores +============ + + ++ La diferencia entre un contador y un acumulador es que en contadores el + el valor agregado es constante, y en acumuladores, variable. + ++ Cálculo de la suma de diez números enteros + + +.. activecode:: ac_l15_4a + :nocodelens: + :stdin: + + n = 1 + suma = 0 + while n <= 10: + x = int(input("Ingrese el último %d número: " %n)) + suma = suma + x + n = n + 1 + + print("suma: %d" %suma) + + ++ Promedio de 10 números enteros + + +.. activecode:: ac_l15_4b + :nocodelens: + :stdin: + + n = 0 + suma = 0 + while n < 10: + x = int(input("Ingrese el último %d número: " %(n + 1))) + suma = suma + x + n = n + 1 + + print("Promedio: %5.2f" %(suma / n)) + + ++ Calcular el factorial de diez + +.. codelens:: cl_l15_4 + + i = 1 + fact = 1 + while i <= 10: + fact = fact * i + i = i + 1 + print("Fact(10) = %d" %fact) + + ++ Calcular el factorial de un número entero ``n`` + +.. activecode:: ac_l15_4c + :nocodelens: + :stdin: + + i = 1 + fact = 1 + n = int(input("Ingrese n: ")) + while i <= n: + fact = fact * i + i = i + 1 + + print("Fact(%d) = %d" %(n, fact)) diff --git a/293/_sources/lectures/TWP15/TWP15_4_en.rst.txt b/293/_sources/lectures/TWP15/TWP15_4_en.rst.txt new file mode 100644 index 0000000000..8b41f46327 --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_4_en.rst.txt @@ -0,0 +1,66 @@ +Accumulators +============= + ++ The difference between a counter and an accumulator is that for counters, + the added value is constant, and for accumulators, it is variable. + ++ Calculation of the sum of ten integer numbers + + +.. activecode:: ac_l15_4a_en + :nocodelens: + :stdin: + + n = 1 + suma = 0 + while n <= 10: + x = int (input ("Enter the last %d number: "% n)) + suma = suma + x + n = n + 1 + + print ("suma: %d"% suma) + + ++ Average of 10 integer numbers + + +.. activecode:: ac_l15_4b_en + :nocodelens: + :stdin: + + n = 0 + suma = 0 + while n <10: + x = int (input ("Enter the last %d number: "% (n + 1))) + suma = suma + x + n = n + 1 + + print ("Average: %5.2f"% (suma / n)) + + ++ Calculate the factorial of ten + +.. codelens:: cl_l15_4_en + + i = 1 + fact = 1 + while i <= 10: + fact = fact * i + i = i + 1 + print ("Fact(10) =% d"% fact) + + ++ Calculate the factorial of an integer number ``n`` + +.. activecode:: ac_l15_4c_en + :nocodelens: + :stdin: + + i = 1 + fact = 1 + n = int (input ("Enter n: ")) + while i <= n: + fact = fact * i + i = i + 1 + + print ("Fact(%d) =% d"% (n, fact)) \ No newline at end of file diff --git a/293/_sources/lectures/TWP15/TWP15_5.rst.txt b/293/_sources/lectures/TWP15/TWP15_5.rst.txt new file mode 100644 index 0000000000..7d7ef531f9 --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_5.rst.txt @@ -0,0 +1,39 @@ +Interrumpiendo la repetición +============================ + + ++ Calcule la suma de números enteros hasta que se ingrese cero + + +.. activecode:: ac_l15_5a + :nocodelens: + :stdin: + + suma = 0 + while True: + x = int(input("Ingrese un numero (0 salir): ")) + if x == 0: + break + suma = suma + x + + print("Suma: %d" %suma) + + ++ Calcule el promedio de los números ingresados hasta que se ingrese cero + + +.. activecode:: ac_l15_5b + :nocodelens: + :stdin: + + suma = 0 + n = 0 + while True: + x = int(input("Ingrese un numero (0 salir): ")) + if x == 0: + break + else: + n = n + 1 + suma = suma + x + + print("Media: %5.2f" %(suma / n)) diff --git a/293/_sources/lectures/TWP15/TWP15_5_en.rst.txt b/293/_sources/lectures/TWP15/TWP15_5_en.rst.txt new file mode 100644 index 0000000000..0da778e13d --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_5_en.rst.txt @@ -0,0 +1,39 @@ +Interrupting the repetition +============================ + + ++ Calculate the sum of integers until zero is entered + + +.. activecode:: ac_l15_5a_en + :nocodelens: + :stdin: + + sum = 0 + while True: + x = int(input("Enter a number (0 to exit): ")) + if x == 0: + break + sum = sum + x + + print("Sum: %d" %sum) + + ++ Calculate the average of entered numbers until zero is entered + + +.. activecode:: ac_l15_5b_en + :nocodelens: + :stdin: + + sum = 0 + n = 0 + while True: + x = int(input("Enter a number (0 to exit): ")) + if x == 0: + break + else: + n = n + 1 + sum = sum + x + + print("Average: %5.2f" %(sum / n)) \ No newline at end of file diff --git a/293/_sources/lectures/TWP15/TWP15_6.rst.txt b/293/_sources/lectures/TWP15/TWP15_6.rst.txt new file mode 100644 index 0000000000..0173209792 --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_6.rst.txt @@ -0,0 +1,29 @@ +Repeticiones anidadas +===================== + + ++ Imprime las tablas de multiplicar del 1 al 10 + + +.. activecode:: ac_l15_6 + :nocodelens: + :stdin: + + tabla_de_multiplicar = 1 + while tabla_de_multiplicar <= 10: + n = 1 + print("\nTabla de multiplicar del %d" %tabla_de_multiplicar) + while n <= 10: + print("%d x %d = %d" %(tabla_de_multiplicar, n, tabla_de_multiplicar * n)) + n = n + 1 + tabla_de_multiplicar = tabla_de_multiplicar + 1 + + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + + +“La vida es como andar en bicicleta. Para mantener el equilibrio, debes seguir moviéndote”. - Einstein diff --git a/293/_sources/lectures/TWP15/TWP15_6_en.rst.txt b/293/_sources/lectures/TWP15/TWP15_6_en.rst.txt new file mode 100644 index 0000000000..13ea358ffc --- /dev/null +++ b/293/_sources/lectures/TWP15/TWP15_6_en.rst.txt @@ -0,0 +1,27 @@ +Nested loops +============= + ++ Prints multiplication tables from 1 to 10 + + +.. activecode:: ac_l15_6_en + :nocodelens: + :stdin: + + multiplication_table = 1 + while multiplication_table <= 10: + n = 1 + print("\nMultiplication table of %d" %multiplication_table) + while n <= 10: + print("%d x %d = %d" %(multiplication_table, n, multiplication_table * n)) + n = n + 1 + multiplication_table = multiplication_table + 1 + + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +"Life is like riding a bicycle. To keep your balance, you must keep moving" - Einstein \ No newline at end of file diff --git a/293/_sources/lectures/TWP15/toctree.rst.txt b/293/_sources/lectures/TWP15/toctree.rst.txt new file mode 100644 index 0000000000..491cd87a3e --- /dev/null +++ b/293/_sources/lectures/TWP15/toctree.rst.txt @@ -0,0 +1,23 @@ +============ +Repeticiones +============ + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP15_1.rst + TWP15_2.rst + TWP15_3.rst + TWP15_4.rst + TWP15_5.rst + TWP15_6.rst diff --git a/293/_sources/lectures/TWP15/toctree_en.rst.txt b/293/_sources/lectures/TWP15/toctree_en.rst.txt new file mode 100644 index 0000000000..153b1dde61 --- /dev/null +++ b/293/_sources/lectures/TWP15/toctree_en.rst.txt @@ -0,0 +1,23 @@ +============ +Repetitions +============ + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP15_1_en.rst + TWP15_2_en.rst + TWP15_3_en.rst + TWP15_4_en.rst + TWP15_5_en.rst + TWP15_6_en.rst diff --git a/293/_sources/lectures/TWP17/TWP17_1.rst.txt b/293/_sources/lectures/TWP17/TWP17_1.rst.txt new file mode 100644 index 0000000000..f42a86d63c --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_1.rst.txt @@ -0,0 +1,25 @@ +Edificio +======== + ++ Edificio de apartamentos + +.. codelens:: cl_l17_1a + + edificio_planta_baja = "La Familia Souza" + edificio_1ra_planta = "La Familia Brito" + edificio_2da_planta = "El Sr Jorge" + edificio_3ra_planta = "La Familia Tanaka" + ++ Podemos asociar la planta baja con la planta baja, la primera es la planta 1 y etc. + + +.. codelens:: cl_l17_1b + + edificio = ["La Familia Souza", + "La Familia Brito", + "El Sr Jorge", + "La Familia Tanaka"] + print(edificio[0]) + print(edificio[1]) + print(edificio[2]) + print(edificio[3]) diff --git a/293/_sources/lectures/TWP17/TWP17_1_en.rst.txt b/293/_sources/lectures/TWP17/TWP17_1_en.rst.txt new file mode 100644 index 0000000000..a9f88929a9 --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_1_en.rst.txt @@ -0,0 +1,24 @@ +Building +======== + ++ Apartment building + +.. codelens:: cl_l17_1a_en + + ground_floor_building = "Souza Family" + first_floor_building = "Brito Family" + second_floor_building = "Mr. Jorge" + third_floor_building = "Tanaka Family" + ++ We can associate the ground floor with the ground floor, the first floor with floor 1, and so on. + +.. codelens:: cl_l17_1b_en + + building = ["Souza Family", + "Brito Family", + "Mr. Jorge", + "Tanaka Family"] + print(building[0]) + print(building[1]) + print(building[2]) + print(building[3]) \ No newline at end of file diff --git a/293/_sources/lectures/TWP17/TWP17_2.rst.txt b/293/_sources/lectures/TWP17/TWP17_2.rst.txt new file mode 100644 index 0000000000..99e605fd67 --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_2.rst.txt @@ -0,0 +1,38 @@ +Tren de datos +============= + +.. image:: ../img/TWP17_004.jpg + :height: 12.8cm + :width: 16.244cm + :align: center + :alt: + + +.. image:: ../img/TWP17_005.png + :height: 8.2cm + :width: 24.756cm + :align: center + :alt: + + ++ El tren de datos ``my_array`` es una variable única. + +Puedo enganchar vagones +----------------------- + +.. image:: ../img/TWP17_006.png + :height: 10cm + :width: 25.303cm + :align: center + :alt: + ++ ¿Cómo puedo agregar un vagón con "Bettys"? + +Puedo unir los vagones con el método ``append()`` +------------------------------------------------- + +.. image:: ../img/TWP17_007.png + :height: 8cm + :width: 24.242cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP17/TWP17_2_en.rst.txt b/293/_sources/lectures/TWP17/TWP17_2_en.rst.txt new file mode 100644 index 0000000000..e7df97cd4d --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_2_en.rst.txt @@ -0,0 +1,38 @@ +Data Train +========== + +.. image:: ../img/TWP17_004.jpg + :height: 12.8cm + :width: 16.244cm + :align: center + :alt: + + +.. image:: ../img/TWP17_005.png + :height: 8.2cm + :width: 24.756cm + :align: center + :alt: + + ++ The data train ``my_array`` is a unique variable. + +I can couple cars +----------------- + +.. image:: ../img/TWP17_006.png + :height: 10cm + :width: 25.303cm + :align: center + :alt: + ++ How can I add a car with "Bettys"? + +I can link the cars with the method ``append()`` +------------------------------------------------ + +.. image:: ../img/TWP17_007.png + :height: 8cm + :width: 24.242cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP17/TWP17_3.rst.txt b/293/_sources/lectures/TWP17/TWP17_3.rst.txt new file mode 100644 index 0000000000..397bc7d13d --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_3.rst.txt @@ -0,0 +1,43 @@ +Sintaxis de una lista +===================== + ++ Una lista vacía + +.. codelens:: cl_l17_3a + + lista = [] + ++ Una lista con tres notas. + +.. codelens:: cl_l17_3b + + notas = [7.5, 9, 8.3] + ++ Accediendo a una nota. + +.. codelens:: cl_l17_3c + + notas = [7.5, 9, 8.3] + print(notas[0]) + ++ Cambiar la primera nota + +.. codelens:: cl_l17_3d + + notas = [7.5, 9, 8.3] + notas[0] = 8.7 + print(notas[0]) + ++ Promedio de 5 notas + +.. codelens:: cl_l17_3e + + notas = [6, 7, 5, 8, 9] + suma = 0 + x = 0 + while x < 5: + suma += notas[x] + x += 1 + print("Media : %5.2f" % (suma / x)) + ++ **Nota**: ``x += 1`` es lo mismo que ``x = x + 1`` diff --git a/293/_sources/lectures/TWP17/TWP17_3_en.rst.txt b/293/_sources/lectures/TWP17/TWP17_3_en.rst.txt new file mode 100644 index 0000000000..c63923eca6 --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_3_en.rst.txt @@ -0,0 +1,43 @@ +Syntax of a List +================ + ++ An empty list + +.. codelens:: cl_l17_3a_en + + lista = [] + ++ A list with three grades. + +.. codelens:: cl_l17_3b_en + + grades = [7.5, 9, 8.3] + ++ Accessing a grade. + +.. codelens:: cl_l17_3c_en + + grades = [7.5, 9, 8.3] + print(grades[0]) + ++ Changing the first grade. + +.. codelens:: cl_l17_3d_en + + grades = [7.5, 9, 8.3] + grades[0] = 8.7 + print(grades[0]) + ++ Average of 5 grades. + +.. codelens:: cl_l17_3e_en + + grades = [6, 7, 5, 8, 9] + sum = 0 + x = 0 + while x < 5: + sum += grades[x] + x += 1 + print("Average: %5.2f" % (sum / x)) + ++ **Note:** ``x += 1`` is the same as ``x = x + 1``. \ No newline at end of file diff --git a/293/_sources/lectures/TWP17/TWP17_4.rst.txt b/293/_sources/lectures/TWP17/TWP17_4.rst.txt new file mode 100644 index 0000000000..003bf9c3b3 --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_4.rst.txt @@ -0,0 +1,91 @@ +Algunos ejemplos +================ + ++ Haga un programa que lea un vector de 5 números enteros y muestre vector. + +.. activecode:: ac_l17_4a + :nocodelens: + :stdin: + + vector = [] + i = 1 + while i <= 5: + n = int(input("Ingrese un numero: ")) + vector.append(n) + i = i + 1 + print("Vector de lectura :", vector) + + ++ Haga un programa que lea un vector de diez números reales y los muestre en orden inverso + +.. activecode:: ac_l17_4b + :nocodelens: + :stdin: + + vector = [] + i = 1 + while i <= 10: + n = float(input("Ingrese un numero: ")) + vector.append(n) + i += 1 + i = 9 + while i >= 0: + print(vector[i]) + i -= 1 + ++ Haga un programa que lea cuatro notas, muestre las notas y el promedio en pantalla + +.. activecode:: ac_l17_4c + :nocodelens: + :stdin: + + notas = [] + i = 1 + while i <= 4: + n = float(input("Nota: ")) + notas.append(n) + i += 1 + suma = 0 + i = 0 + while i <= 3: + suma += notas[i] + i += 1 + print("Notas:", notas) + print("Media : %4.2f" % (suma / 4)) + ++ Otra forma de hacer lo mismo. + +.. activecode:: ac_l17_4d + :nocodelens: + :stdin: + + notas = [] + i = 1 + suma = 0 + while i <= 4: + n = float(input("Nota: ")) + notas.append(n) + suma += n + i += 1 + print("Notas:", notas) + print("Media : %4.2f" % (suma / 4)) + + ++ Haga un programa que lea un vector de 10 caracteres en minúscula, y diga cuántas consonantes se leyeron. + +.. activecode:: ac_l17_4e + :nocodelens: + :stdin: + + letras = [] + i = 1 + while i <= 10: + letras.append(input("Letra: ")) + i += 1 + i = 0 + cont = 0 + while i <= 9: + if letras[i] not in "aeiou": + cont += 1 + i += 1 + print("Fueron leídos %d consonantes" % cont) diff --git a/293/_sources/lectures/TWP17/TWP17_4_en.rst.txt b/293/_sources/lectures/TWP17/TWP17_4_en.rst.txt new file mode 100644 index 0000000000..8de9a05ab3 --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_4_en.rst.txt @@ -0,0 +1,91 @@ +Some examples +============= + ++ Make a program that reads a vector of 5 integers and displays the vector. + +.. activecode:: ac_l17_4a_en + :nocodelens: + :stdin: + + vector = [] + i = 1 + while i <= 5: + n = int(input("Enter a number: ")) + vector.append(n) + i = i + 1 + print("Read vector:", vector) + + ++ Make a program that reads a vector of ten real numbers and displays them in reverse order. + +.. activecode:: ac_l17_4b_en + :nocodelens: + :stdin: + + vector = [] + i = 1 + while i <= 10: + n = float(input("Enter a number: ")) + vector.append(n) + i += 1 + i = 9 + while i >= 0: + print(vector[i]) + i -= 1 + ++ Make a program that reads four grades, displays the grades, and the average on the screen. + +.. activecode:: ac_l17_4c_en + :nocodelens: + :stdin: + + grades = [] + i = 1 + while i <= 4: + n = float(input("Grade: ")) + grades.append(n) + i += 1 + suma = 0 + i = 0 + while i <= 3: + suma += grades[i] + i += 1 + print("Grades:", grades) + print("Average: %4.2f" % (suma / 4)) + ++ Another way of doing the same thing. + +.. activecode:: ac_l17_4d_en + :nocodelens: + :stdin: + + grades = [] + i = 1 + suma = 0 + while i <= 4: + n = float(input("Grade: ")) + grades.append(n) + suma += n + i += 1 + print("Grades:", grades) + print("Average: %4.2f" % (suma / 4)) + + ++ Make a program that reads a vector of 10 lowercase characters, and tells how many consonants were read. + +.. activecode:: ac_l17_4e_en + :nocodelens: + :stdin: + + letters = [] + i = 1 + while i <= 10: + letters.append(input("Letter: ")) + i += 1 + i = 0 + cont = 0 + while i <= 9: + if letters[i] not in "aeiou": + cont += 1 + i += 1 + print("%d consonants were read" % cont) \ No newline at end of file diff --git a/293/_sources/lectures/TWP17/TWP17_5.rst.txt b/293/_sources/lectures/TWP17/TWP17_5.rst.txt new file mode 100644 index 0000000000..ebabbeba89 --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_5.rst.txt @@ -0,0 +1,10 @@ +Lista de Ejercícios “again” +=========================== + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +“La vida es como andar en bicicleta. Para mantener el equilibrio, debes seguir moviéndote”. - Einstein diff --git a/293/_sources/lectures/TWP17/TWP17_5_en.rst.txt b/293/_sources/lectures/TWP17/TWP17_5_en.rst.txt new file mode 100644 index 0000000000..384eabb599 --- /dev/null +++ b/293/_sources/lectures/TWP17/TWP17_5_en.rst.txt @@ -0,0 +1,10 @@ +Exercise List "again" +=========================== + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +"Life is like riding a bicycle. To keep your balance, you must keep moving." - Einstein \ No newline at end of file diff --git a/293/_sources/lectures/TWP17/toctree.rst.txt b/293/_sources/lectures/TWP17/toctree.rst.txt new file mode 100644 index 0000000000..7cc46ae83d --- /dev/null +++ b/293/_sources/lectures/TWP17/toctree.rst.txt @@ -0,0 +1,22 @@ +====== +Listas +====== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP17_1.rst + TWP17_2.rst + TWP17_3.rst + TWP17_4.rst + TWP17_5.rst diff --git a/293/_sources/lectures/TWP17/toctree_en.rst.txt b/293/_sources/lectures/TWP17/toctree_en.rst.txt new file mode 100644 index 0000000000..4ea6c6ee76 --- /dev/null +++ b/293/_sources/lectures/TWP17/toctree_en.rst.txt @@ -0,0 +1,22 @@ +====== +Lists +====== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP17_1_en.rst + TWP17_2_en.rst + TWP17_3_en.rst + TWP17_4_en.rst + TWP17_5_en.rst diff --git a/293/_sources/lectures/TWP18/TWP18_1.rst.txt b/293/_sources/lectures/TWP18/TWP18_1.rst.txt new file mode 100644 index 0000000000..8cf8e6cec9 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_1.rst.txt @@ -0,0 +1,21 @@ +Comillas de varios tipos +======================== + ++ ¿Puedo usar comillas simples, dobles o triples? + + +.. codelens:: cl_l18_1 + + x = 'aguacate' + print(x) + y = "McDonald's" + print(y) + formulario = """ + + + Prueba + + +

Probando

+ + """ diff --git a/293/_sources/lectures/TWP18/TWP18_1_en.rst.txt b/293/_sources/lectures/TWP18/TWP18_1_en.rst.txt new file mode 100644 index 0000000000..d2af2545c4 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_1_en.rst.txt @@ -0,0 +1,21 @@ +Quotes of various types +======================== + ++ Can I use single, double or triple quotes? + + +.. codelens:: cl_l18_1_en + + x = 'avocado' + print(x) + y = "McDonald's" + print(y) + form = """ + + + Test + + +

Testing

+ + """ \ No newline at end of file diff --git a/293/_sources/lectures/TWP18/TWP18_2.rst.txt b/293/_sources/lectures/TWP18/TWP18_2.rst.txt new file mode 100644 index 0000000000..bf0fd41012 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_2.rst.txt @@ -0,0 +1,54 @@ +Rebanar +======= + ++ Rebanada del primer índice al anterior del segundo + +.. codelens:: cl_l18_2a + + x = "0123456789" + print(x[0:2]) + print(x[1:2]) + print(x[2:4]) + print(x[0:5]) + print(x[1:8]) + + ++ Podemos omitir índices, sustituyendo el extremo correspondiente y + también podemos tener índices negativos: -1 último, -2 penúltimo + + +.. codelens:: cl_l18_2b + + x = "0123456789" + print(x[:2]) + print(x[4:]) + print(x[4:-1]) + print(x[-4:-1]) + print(x[:]) + + +Incremento en el corte +---------------------- + ++ Puedo usar un incremento al cortar el string + + +.. codelens:: cl_l18_2c + + texto = "papa cuando nace" + print(texto[::2]) + print(texto[::-1]) + + ++ Comprobar si una palabra es palíndrome + + +.. activecode:: ac_l18_2 + :nocodelens: + :stdin: + + palabra = input("Palabra: ") + if palabra == palabra[::-1]: + print("%s es palíndrome" % palabra) + else: + print("%s no es un palíndrome" % palabra) diff --git a/293/_sources/lectures/TWP18/TWP18_2_en.rst.txt b/293/_sources/lectures/TWP18/TWP18_2_en.rst.txt new file mode 100644 index 0000000000..fce435dab5 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_2_en.rst.txt @@ -0,0 +1,54 @@ +Slicing +======= + ++ Slice from the first index to the one before the second + +.. codelens:: cl_l18_2a_en + + x = "0123456789" + print(x[0:2]) + print(x[1:2]) + print(x[2:4]) + print(x[0:5]) + print(x[1:8]) + + ++ We can omit indices by substituting the corresponding end and + we can also have negative indices: -1 is the last one, -2 the penultimate + + +.. codelens:: cl_l18_2b_en + + x = "0123456789" + print(x[:2]) + print(x[4:]) + print(x[4:-1]) + print(x[-4:-1]) + print(x[:]) + + +Slice increment +--------------- + ++ I can use an increment when slicing the string + + +.. codelens:: cl_l18_2c_en + + texto = "papa cuando nace" + print(texto[::2]) + print(texto[::-1]) + + ++ Check if a word is a palindrome + + +.. activecode:: ac_l18_2_en + :nocodelens: + :stdin: + + word = input("Word: ") + if word == word[::-1]: + print("%s is a palindrome" % word) + else: + print("%s is not a palindrome" % word) \ No newline at end of file diff --git a/293/_sources/lectures/TWP18/TWP18_3.rst.txt b/293/_sources/lectures/TWP18/TWP18_3.rst.txt new file mode 100644 index 0000000000..8550998e91 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_3.rst.txt @@ -0,0 +1,78 @@ +Concatenación +============= + +Una String no se puede modificar +-------------------------------- + +.. activecode:: ac_l18_3a + :nocodelens: + :stdin: + + texto = " Hola mundo!" + texto[0] = "@" + + +Puedo crear nuevos strings +-------------------------- + ++ Usando la concatenación resolvemos este problema + + +.. activecode:: ac_l18_3b + :nocodelens: + :stdin: + + texto = "Hola mundo" + texto = "@" + texto[1:] + print(texto) + + ++ Ejemplo de un programa que lee una palabra y reemplaza las vocales por ``"*"``. + La función ``lower`` transforma las letras en minúsculas. + + +.. activecode:: ac_l18_3c + :nocodelens: + :stdin: + + palabra = input("Palabra: ") + k = 0 + intercambio = "" + while k < len(palabra): + if palabra[k].lower() in "aeiou": + intercambio = intercambio + "*" + else: + intercambio = intercambio + palabra[k] + k += 1 + print("Nueva palabra %s" % intercambio) + + +Ejercicio +--------- + +.. activecode:: ac_l18_3d + :nocodelens: + :stdin: + + Ahora haga un programa que lea una palabra, la guarde en la variable ``palabra``, + y reemplace las consonantes con ``"*"``. Guardar el resultado en la variable ``intercambio``. + Puede apoyarse en el programa anterior. + + ~~~~ + # Utilice la función input para leer la palabra del usuario. + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual( + intercambio, + "".join(["*" if c.lower() not in "aeiou" else c for c in palabra]), + "Probando que intercambio esté asignado correctamente", + ) + + + myTests().main() diff --git a/293/_sources/lectures/TWP18/TWP18_3_en.rst.txt b/293/_sources/lectures/TWP18/TWP18_3_en.rst.txt new file mode 100644 index 0000000000..686c2acb69 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_3_en.rst.txt @@ -0,0 +1,77 @@ +Concatenation +============= + +A string cannot be modified +-------------------------------- + +.. activecode:: ac_l18_3a_en + :nocodelens: + :stdin: + + texto = " Hello world!" + texto[0] = "@" + +I can create new strings +-------------------------- + ++ Using concatenation solves this problem + + +.. activecode:: ac_l18_3b_en + :nocodelens: + :stdin: + + texto = "Hello world" + texto = "@" + texto[1:] + print(texto) + + ++ Example of a program that reads a word and replaces the vowels with ``"*"``. + The ``lower`` function transforms the letters to lowercase. + + +.. activecode:: ac_l18_3c_en + :nocodelens: + :stdin: + + palabra = input("Word: ") + k = 0 + intercambio = "" + while k < len(palabra): + if palabra[k].lower() in "aeiou": + intercambio = intercambio + "*" + else: + intercambio = intercambio + palabra[k] + k += 1 + print("New word %s" % intercambio) + + +Exercise +--------- + +.. activecode:: ac_l18_3d_en + :nocodelens: + :stdin: + + # Now create a program that reads a word, saves it in the variable "palabra", + # and replaces the consonants with "*". Save the result in the variable "intercambio". + # You can use the previous program as a reference. + + ~~~~ + # Use the input function to read the word from the user. + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual( + intercambio, + "".join(["*" if c.lower() not in "aeiou" else c for c in palabra]), + "Testing that intercambio is correctly assigned", + ) + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/lectures/TWP18/TWP18_4.rst.txt b/293/_sources/lectures/TWP18/TWP18_4.rst.txt new file mode 100644 index 0000000000..0ae38d78d3 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_4.rst.txt @@ -0,0 +1,13 @@ +Verificación parcial de strings +=============================== + + +.. codelens:: cl_l18_4 + + archivo = "prog.py" + print(archivo.startswith("p")) + print(archivo.endswith("p")) + contestar = "Si" + print(contestar.lower()) + print(contestar.upper()) + print(contestar.lower() in "si no yes no") diff --git a/293/_sources/lectures/TWP18/TWP18_4_en.rst.txt b/293/_sources/lectures/TWP18/TWP18_4_en.rst.txt new file mode 100644 index 0000000000..0cff1ec5a1 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_4_en.rst.txt @@ -0,0 +1,13 @@ +Partial verification of strings +=============================== + + +.. codelens:: cl_l18_4_en + + file = "prog.py" + print(file.startswith("p")) + print(file.endswith("p")) + answer = "Yes" + print(answer.lower()) + print(answer.upper()) + print(answer.lower() in "yes no") \ No newline at end of file diff --git a/293/_sources/lectures/TWP18/TWP18_5.rst.txt b/293/_sources/lectures/TWP18/TWP18_5.rst.txt new file mode 100644 index 0000000000..a23b6d3a8f --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_5.rst.txt @@ -0,0 +1,13 @@ +Funciones ``find`` y ``replace`` +================================ + + +.. codelens:: cl_l18_5 + + s = "un tigre, dos tigres, tres tigres" + print(s.find("tigre")) + print(s.find("tigre", 4)) + print(s.find("tigre", 16)) + print(s.replace("tigre", "gato")) + s = s.replace("tigre", "gato") + print(s) diff --git a/293/_sources/lectures/TWP18/TWP18_5_en.rst.txt b/293/_sources/lectures/TWP18/TWP18_5_en.rst.txt new file mode 100644 index 0000000000..a747d4ce63 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_5_en.rst.txt @@ -0,0 +1,13 @@ +Functions ``find`` and ``replace`` +================================== + + +.. codelens:: cl_l18_5_en + + s = "one tiger, two tigers, three tigers" + print(s.find("tiger")) + print(s.find("tiger", 4)) + print(s.find("tiger", 16)) + print(s.replace("tiger", "cat")) + s = s.replace("tiger", "cat") + print(s) \ No newline at end of file diff --git a/293/_sources/lectures/TWP18/TWP18_6.rst.txt b/293/_sources/lectures/TWP18/TWP18_6.rst.txt new file mode 100644 index 0000000000..73542eca39 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_6.rst.txt @@ -0,0 +1,64 @@ +Funciones ``split`` y ``join`` +============================== + +.. codelens:: cl_l18_6 + + texto = "papa cuando nace" + print(texto.split()) + fecha = "21/02/2011" + print(fecha.split("/")) + ip = "198.188.10.144" + print(ip.split(".")) + lugares = ["Palmeiras", "Santos", "Corintios"] + print("/".join(lugares)) + + +Ejercicio +--------- + + +.. activecode:: ac_l18_6 + :nocodelens: + :stdin: + + Haga un programa que solicite la fecha de nacimiento en formato "dd/mm/aaaa" y + convierta esta fecha a formato " de de " usando la lista ``meses`` + que ya está escrita. Guardar el resultado en la variable ``fecha_de_nacimiento`` e + imprimir esta variable. Recordar que ``.split()`` regresa una lista y se le puede pasar + como argumento el caracter con el cual separar un string. Guardar el día, mes y el año en formato de cadena + en las variables ``dia``, ``mes`` y ``anio``. + + ~~~~ + fecha = input("fecha (dd/mm/aaaa): ").split("/") + meses = [ + "enero", + "febrero", + "marzo", + "abril", + "mayo", + "junio", + "julio", + "agosto", + "septiembre", + "octubre", + "noviembre", + "diciembre", + ] + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual( + fecha_de_nacimiento, + "{} de {} de {}".format(dia, meses[int(mes) - 1], anio), + "Probando que fecha_de_nacimiento esté asignada correctamente", + ) + self.assertEqual(dia, fecha[0], "Probando que dia esté asignada correctamente") + self.assertEqual(mes, fecha[1], "Probando que mes esté asignado correctamente") + self.assertEqual(anio, fecha[2], "Probando que anio esté asignado correctamente") + + + myTests().main() diff --git a/293/_sources/lectures/TWP18/TWP18_6_en.rst.txt b/293/_sources/lectures/TWP18/TWP18_6_en.rst.txt new file mode 100644 index 0000000000..5a1a81f718 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_6_en.rst.txt @@ -0,0 +1,62 @@ +Functions ``split`` and ``join`` +================================= + +.. codelens:: cl_l18_6_en + + text = "potato when born" + print(text.split()) + date = "02/21/2011" + print(date.split("/")) + ip = "198.188.10.144" + print(ip.split(".")) + places = ["Palmeiras", "Santos", "Corinthians"] + print("/".join(places)) + + +Exercise +-------- + +.. activecode:: ac_l18_6_en + :nocodelens: + :stdin: + + Write a program that asks for a birth date in the format "dd/mm/yyyy" and + converts this date to the format " of of " using the pre-written list + ``months``. Save the result in the variable ``birth_date`` and print this variable. Remember + that ``.split()`` returns a list and you can pass the character to separate a string as an argument. + Save the day, month and year in string format in the variables ``day``, ``month`` and ``year``. + + ~~~~ + date = input("date (dd/mm/yyyy): ").split("/") + months = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + ] + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual( + birth_date, + "{} of {} of {}".format(day, months[int(month) - 1], year), + "Testing that birth_date is assigned correctly", + ) + self.assertEqual(day, date[0], "Testing that day is assigned correctly") + self.assertEqual(month, date[1], "Testing that month is assigned correctly") + self.assertEqual(year, date[2], "Testing that year is assigned correctly") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/lectures/TWP18/TWP18_7.rst.txt b/293/_sources/lectures/TWP18/TWP18_7.rst.txt new file mode 100644 index 0000000000..d95860c7b5 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_7.rst.txt @@ -0,0 +1,42 @@ +Dojo de codificación +==================== + +.. image:: ../img/TWP18_015.jpeg + :height: 14.251cm + :width: 19.001cm + :align: center + :alt: + ++ Desarrollo basado en pruebas ++ Pasos de bebé ++ Programación de pares + + +Desarrollo basado en pruebas +---------------------------- + +.. image:: ../img/TWP18_016.png + :height: 11.032cm + :width: 17.726cm + :align: center + :alt: + + +Pasos de bebé +------------- + +.. image:: ../img/TWP18_017.jpeg + :height: 12.624cm + :width: 17.704cm + :align: center + :alt: + + +Programación en pareja +---------------------- + +.. image:: ../img/TWP18_018.png + :height: 13.711cm + :width: 18.201cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP18/TWP18_7_en.rst.txt b/293/_sources/lectures/TWP18/TWP18_7_en.rst.txt new file mode 100644 index 0000000000..d0cec891a8 --- /dev/null +++ b/293/_sources/lectures/TWP18/TWP18_7_en.rst.txt @@ -0,0 +1,42 @@ +Coding Dojo +=========== + +.. image:: ../img/TWP18_015.jpeg + :height: 14.251cm + :width: 19.001cm + :align: center + :alt: + ++ Test-driven development ++ Baby steps ++ Pair programming + + +Test-driven development +------------------------ + +.. image:: ../img/TWP18_016.png + :height: 11.032cm + :width: 17.726cm + :align: center + :alt: + + +Baby steps +---------- + +.. image:: ../img/TWP18_017.jpeg + :height: 12.624cm + :width: 17.704cm + :align: center + :alt: + + +Pair programming +----------------- + +.. image:: ../img/TWP18_018.png + :height: 13.711cm + :width: 18.201cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP18/toctree.rst.txt b/293/_sources/lectures/TWP18/toctree.rst.txt new file mode 100644 index 0000000000..b28b8df681 --- /dev/null +++ b/293/_sources/lectures/TWP18/toctree.rst.txt @@ -0,0 +1,24 @@ +======= +Strings +======= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP18_1.rst + TWP18_2.rst + TWP18_3.rst + TWP18_4.rst + TWP18_5.rst + TWP18_6.rst + TWP18_7.rst diff --git a/293/_sources/lectures/TWP18/toctree_en.rst.txt b/293/_sources/lectures/TWP18/toctree_en.rst.txt new file mode 100644 index 0000000000..51c63ae76b --- /dev/null +++ b/293/_sources/lectures/TWP18/toctree_en.rst.txt @@ -0,0 +1,24 @@ +======= +Strings +======= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP18_1_en.rst + TWP18_2_en.rst + TWP18_3_en.rst + TWP18_4_en.rst + TWP18_5_en.rst + TWP18_6_en.rst + TWP18_7_en.rst diff --git a/293/_sources/lectures/TWP20/TWP20_1.rst.txt b/293/_sources/lectures/TWP20/TWP20_1.rst.txt new file mode 100644 index 0000000000..0dec3856dc --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_1.rst.txt @@ -0,0 +1,53 @@ +for == while oculto +=================== + ++ Códigos equivalentes: FOR durante el día se convierte WHILE por la noche. + + +.. codelens:: cl_l20_1a + + for letra in "aeiou": + print(letra) + +.. codelens:: cl_l20_1b + + texto = "aeiou" + k = 0 + while k < len(texto): + letra = texto[k] + print(letra) + k = k + 1 + + ++ Códigos equivalentes: + +.. codelens:: cl_l20_1c + + for i in range(5): + print(i) + +.. codelens:: cl_l20_1d + + lista = list(range(5)) + k = 0 + while k < len(lista): + i = lista[k] + print(i) + k = k + 1 + + ++ Códigos equivalentes: + +.. codelens:: cl_l20_1e + + for x in ["cpbr6", 42, 3.14]: + print(x) + +.. codelens:: cl_l20_1f + + lista = ["cpbr6", 42, 3.14] + k = 0 + while k < len(lista): + x = lista[k] + print(x) + k = k + 1 diff --git a/293/_sources/lectures/TWP20/TWP20_1_en.rst.txt b/293/_sources/lectures/TWP20/TWP20_1_en.rst.txt new file mode 100644 index 0000000000..ce98753fe9 --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_1_en.rst.txt @@ -0,0 +1,52 @@ +for == while hidden +====================== + ++ Equivalent codes: FOR during the day becomes WHILE at night. + +.. codelens:: cl_l20_1a_en + + for letter in "aeiou": + print(letter) + +.. codelens:: cl_l20_1b_en + + text = "aeiou" + k = 0 + while k < len(text): + letter = text[k] + print(letter) + k = k + 1 + + ++ Equivalent codes: + +.. codelens:: cl_l20_1c_en + + for i in range(5): + print(i) + +.. codelens:: cl_l20_1d_en + + list = list(range(5)) + k = 0 + while k < len(list): + i = list[k] + print(i) + k = k + 1 + + ++ Equivalent codes: + +.. codelens:: cl_l20_1e_en + + for x in ["cpbr6", 42, 3.14]: + print(x) + +.. codelens:: cl_l20_1f_en + + list = ["cpbr6", 42, 3.14] + k = 0 + while k < len(list): + x = list[k] + print(x) + k = k + 1 \ No newline at end of file diff --git a/293/_sources/lectures/TWP20/TWP20_2.rst.txt b/293/_sources/lectures/TWP20/TWP20_2.rst.txt new file mode 100644 index 0000000000..9fb8dbf117 --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_2.rst.txt @@ -0,0 +1,39 @@ +Funciones ``def`` +================= + ++ Aprendimos algunas funciones de Python: ``len``, ``int``, ``float``, ``print`` e ``input``. ++ Ahora crearemos nuestras propias funciones. ++ Utilizo ``def`` para definir la función y ``return`` para devolver algún valor. ++ Hay funciones que no devuelven nada. + +.. codelens:: cl_l20_2a + + def es_par(x): + return x % 2 == 0 + + + print(es_par(13)) + print(es_par(12)) + + ++ Esta función regresa ``True`` si el parámetro ``x`` es par, ``False`` en caso contrario. ++ Tenga en cuenta que, a diferencia de lo que hemos visto hasta ahora, estas líneas de código no se ejecutarán de inmediato. ++ Es necesario llamar a la función para ejecutarlas. + +Ejemplo +------- + ++ Definir una función ``factorial`` + +.. codelens:: cl_l20_2b + + def factorial(n): + f = 1 + while n > 0: + f = f * n + n = n - 1 + return f + + + for i in range(5): + print(factorial(i)) diff --git a/293/_sources/lectures/TWP20/TWP20_2_en.rst.txt b/293/_sources/lectures/TWP20/TWP20_2_en.rst.txt new file mode 100644 index 0000000000..4385bbec57 --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_2_en.rst.txt @@ -0,0 +1,39 @@ +Functions ``def`` +================= + ++ We learned some Python functions: ``len``, ``int``, ``float``, ``print``, and ``input``. ++ Now we will create our own functions. ++ I use ``def`` to define the function and ``return`` to return a value. ++ There are functions that do not return anything. + +.. codelens:: cl_l20_2a_en + + def is_even(x): + return x % 2 == 0 + + + print(is_even(13)) + print(is_even(12)) + + ++ This function returns ``True`` if the parameter ``x`` is even, ``False`` otherwise. ++ Note that, unlike what we have seen so far, these lines of code will not be executed immediately. ++ It is necessary to call the function to execute them. + +Example +------- + ++ Define a function ``factorial`` + +.. codelens:: cl_l20_2b_en + + def factorial(n): + f = 1 + while n > 0: + f = f * n + n = n - 1 + return f + + + for i in range(5): + print(factorial(i)) \ No newline at end of file diff --git a/293/_sources/lectures/TWP20/TWP20_3.rst.txt b/293/_sources/lectures/TWP20/TWP20_3.rst.txt new file mode 100644 index 0000000000..9e21ab36fb --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_3.rst.txt @@ -0,0 +1,35 @@ +Variables locales y globales +============================ + ++ **Nota**: El alcance de ``a`` en el ejemplo de abajo es diferente en los dos casos. En otras palabras, las dos variables ``a`` son diferentes. + +.. codelens:: cl_l20_3a + + a = 5 + + def cambio_y_impresion(): + a = 7 + print("valor de 'a' dentro de la función : %d" % a) + + + print("valor de 'a' antes de cambiar: %d" % a) + cambio_y_impresion() + print("valor de 'a' después de cambiar: %d" % a) + ++ En este caso, usamos la palabra reservada global. Entonces, la variable ``a`` dentro de la función es la misma que la variable definida anteriormente, es decir, es la variable global. + +.. codelens:: cl_l20_3b + + a = 5 + + def cambio_y_impresion(): + global a + a = 7 + print("valor de a dentro de la función : %d" % a) + + + print("valor de a antes de cambiar: %d" % a) + cambio_y_impresion() + print("valor de a después de cambiar: %d" % a) + ++ Observe la diferencia en las salidas en los ejemplos 9 y 10. diff --git a/293/_sources/lectures/TWP20/TWP20_3_en.rst.txt b/293/_sources/lectures/TWP20/TWP20_3_en.rst.txt new file mode 100644 index 0000000000..d5ce0cdc48 --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_3_en.rst.txt @@ -0,0 +1,35 @@ +Local and Global Variables +============================ + ++ **Note**: The scope of ``a`` in the example below is different in the two cases. In other words, the two variables ``a`` are different. + +.. codelens:: cl_l20_3a_en + + a = 5 + + def change_and_print(): + a = 7 + print("Value of 'a' inside the function: %d" % a) + + + print("Value of 'a' before changing: %d" % a) + change_and_print() + print("Value of 'a' after changing: %d" % a) + ++ In this case, we use the keyword global. So, the variable ``a`` inside the function is the same as the variable defined earlier, that is, it is the global variable. + +.. codelens:: cl_l20_3b_en + + a = 5 + + def change_and_print(): + global a + a = 7 + print("Value of a inside the function: %d" % a) + + + print("Value of a before changing: %d" % a) + change_and_print() + print("Value of a after changing: %d" % a) + ++ Observe the difference in the outputs in examples 9 and 10. \ No newline at end of file diff --git a/293/_sources/lectures/TWP20/TWP20_4.rst.txt b/293/_sources/lectures/TWP20/TWP20_4.rst.txt new file mode 100644 index 0000000000..3eb900e68d --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_4.rst.txt @@ -0,0 +1,68 @@ +Números aleatorios +================== + +.. codelens:: cl_l20_4a + + import random + + print(random.randint(1, 100)) + print(random.randint(1, 100)) + alumnos = ["José", + "Juan", + "Pedro", + "Lucas", + "Thiago"] + print(random.choice(alumnos)) + print(random.choice(alumnos)) + random.shuffle(alumnos) + print(alumnos) + random.shuffle(alumnos) + print(alumnos) + + ++ Se define una función de "codificación" que devuelve las letras en una cadena mezclados. ++ **Nota**: Se usa la función ``list()`` para convertir una cadena en una lista. + +.. codelens:: cl_l20_4b + + import random + + + def codificación(s): + + lista = list(s) + random.shuffle(lista) + return "".join(lista) + + + print(codificación("palmeras")) + print(codificación("palmeras")) + + ++ Genere una lista de 15 enteros aleatorios entre 10 y 100. + +.. codelens:: cl_l20_4c + + import random + + lista = [] + for k in range(15): + lista.append( + random.randint(10, 100) + ) + print(lista) + + ++ Genere una lista de 15 enteros aleatorios entre 10 y 100 que son distintos el uno del otro. + +.. codelens:: cl_l20_4d + + import random + + lista = [] + while len(lista) < 15: + x = random.randint(10, 100) + if x not in lista: + lista.append(x) + lista.sort() + print(lista) diff --git a/293/_sources/lectures/TWP20/TWP20_4_en.rst.txt b/293/_sources/lectures/TWP20/TWP20_4_en.rst.txt new file mode 100644 index 0000000000..94a1c452f6 --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_4_en.rst.txt @@ -0,0 +1,68 @@ +Random numbers +============== + +.. codelens:: cl_l20_4a_en + + import random + + print(random.randint(1, 100)) + print(random.randint(1, 100)) + students = ["Jose", + "Juan", + "Pedro", + "Lucas", + "Thiago"] + print(random.choice(students)) + print(random.choice(students)) + random.shuffle(students) + print(students) + random.shuffle(students) + print(students) + + ++ A "codification" function is defined which returns the letters in a string shuffled. ++ **Note:** the ``list()`` function is used to convert a string into a list. + +.. codelens:: cl_l20_4b_en + + import random + + + def codification(s): + + lst = list(s) + random.shuffle(lst) + return "".join(lst) + + + print(codification("palmeras")) + print(codification("palmeras")) + + ++ Generate a list of 15 random integers between 10 and 100. + +.. codelens:: cl_l20_4c_en + + import random + + lst = [] + for k in range(15): + lst.append( + random.randint(10, 100) + ) + print(lst) + + ++ Generate a list of 15 distinct random integers between 10 and 100. + +.. codelens:: cl_l20_4d_en + + import random + + lst = [] + while len(lst) < 15: + x = random.randint(10, 100) + if x not in lst: + lst.append(x) + lst.sort() + print(lst) \ No newline at end of file diff --git a/293/_sources/lectures/TWP20/TWP20_5.rst.txt b/293/_sources/lectures/TWP20/TWP20_5.rst.txt new file mode 100644 index 0000000000..a87544f58b --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_5.rst.txt @@ -0,0 +1,11 @@ +Lista de ejercicios "again" +=========================== + + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +“La vida es como andar en bicicleta. Para mantener el equilibrio, debes seguir moviéndote”. - Einstein diff --git a/293/_sources/lectures/TWP20/TWP20_5_en.rst.txt b/293/_sources/lectures/TWP20/TWP20_5_en.rst.txt new file mode 100644 index 0000000000..a524c50a79 --- /dev/null +++ b/293/_sources/lectures/TWP20/TWP20_5_en.rst.txt @@ -0,0 +1,11 @@ +Exercise List "again" +=============================== + + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + +"Life is like riding a bicycle. To keep your balance, you must keep moving." - Einstein \ No newline at end of file diff --git a/293/_sources/lectures/TWP20/toctree.rst.txt b/293/_sources/lectures/TWP20/toctree.rst.txt new file mode 100644 index 0000000000..22b6b5fe09 --- /dev/null +++ b/293/_sources/lectures/TWP20/toctree.rst.txt @@ -0,0 +1,22 @@ +======================= +for, random y funciones +======================= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP20_1.rst + TWP20_2.rst + TWP20_3.rst + TWP20_4.rst + TWP20_5.rst diff --git a/293/_sources/lectures/TWP20/toctree_en.rst.txt b/293/_sources/lectures/TWP20/toctree_en.rst.txt new file mode 100644 index 0000000000..4e9f65d754 --- /dev/null +++ b/293/_sources/lectures/TWP20/toctree_en.rst.txt @@ -0,0 +1,22 @@ +========================= +for, random and functions +========================= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP20_1_en.rst + TWP20_2_en.rst + TWP20_3_en.rst + TWP20_4_en.rst + TWP20_5_en.rst diff --git a/293/_sources/lectures/TWP23/TWP23_1.rst.txt b/293/_sources/lectures/TWP23/TWP23_1.rst.txt new file mode 100644 index 0000000000..6f2f81a040 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_1.rst.txt @@ -0,0 +1,92 @@ +Archivos +======== + ++ Hasta ahora nuestros datos desaparecieron al salir de IDLE ++ Los archivos son para almacenamiento permanente ++ Un archivo es un área de disco donde podemos leer o escribir informacion ++ Accedemos al archivo por su nombre ++ Para acceder a un archivo necesita abrirlo ++ Al abrir el archivo informamos su nombre, directorio donde está (si necesario) y qué operaciones realizaremos: lectura y / o escritura ++ La función que abre los archivos está abierta y los modos son: r - lectura, w - escritura, a - agregar, b - binario,(actualizar) ++ Los métodos para leer o escribir son ``read()`` y ``write()`` ++ Los archivos deben cerrarse con ``close()`` + +.. code-block:: python + + archivo = open("numeros.txt", "w") + for numero in range(1, 31): + archivo.write("%d\n" % numero) + archivo.close() + + +.. datafile:: numeros.txt + :cols: 20 + :rows: 10 + :edit: + + +.. activecode:: ac_l23_1a + :nocodelens: + :datafile: numeros.txt + :enabledownload: + + Pruebe el programa anterior: + + ~~~~ + archivo = open("numeros.txt", "w") + for numero in range(1, 31): + archivo.write("%d\n" % numero) + archivo.close() + + + ==== + print("Se han escrito datos en el archivo numeros.txt") + + ++ Al ejecutar el programa anterior se modifica el archivo ``numeros.txt``. ++ El modo w crea el archivo si no existe, si existe será eliminado y reescrito + + +.. activecode:: ac_l23_1b + :nocodelens: + :datafile: numeros.txt + :enabledownload: + + Ya escribió en el archivo ``"numeros.txt"``. Ahora va a leer los datos que ha escrito: + + ~~~~ + archivo = open("numeros.txt", "r") + for linea in archivo.readlines(): + print(linea) + archivo.close() + ++ ``readlines()`` genera una lista donde cada elemento es una línea de lectura. ++ El archivo ``numeros.txt`` ahora tiene escrito números, cada número en una línea diferente. + Este cambio de línea fue inscrito con el carácter especial ``\n``. ++ Si queremos eliminar este carácter del final, podemos usar ``print(linea.rstrip())``. + Pruebe imprimir de esta manera las líneas de texto. + + +Pythonic way +------------ + + +.. code-block:: python + + with open("numeros.txt", "r") as f: + print(f.read()) + +.. activecode:: ac_l23_1c + :nocodelens: + :datafile: numeros.txt + :enabledownload: + + with open("numeros.txt", "r") as f: + print(f.read()) + + ++ El código anterior hace lo mismo para la forma pitónica. ++ En la diapositiva anterior vimos cómo los programadores normales leen ++ Python es genial, porque siempre puedes ir más profundo ++ Python es simple, pero difícil de agotar + diff --git a/293/_sources/lectures/TWP23/TWP23_1_en.rst.txt b/293/_sources/lectures/TWP23/TWP23_1_en.rst.txt new file mode 100644 index 0000000000..fee0b3bf27 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_1_en.rst.txt @@ -0,0 +1,90 @@ +Files +===== + ++ Until now our data disappeared when leaving IDLE ++ Files are for permanent storage ++ A file is a disk area where we can read or write information ++ We access the file by its name ++ To access a file you need to open it ++ When opening the file, we inform its name, directory (if necessary) and what operations we will perform: read and / or write ++ The function that opens files is `open()` and the modes are: r - read, w - write, a - append, b - binary (update) ++ The methods to read or write are `read()` and `write()` ++ Files must be closed with `close()` + +.. code-block:: python + + archive = open("numbers.txt", "w") + for numbers in range(1, 31): + archivo.write("%d\n" % numbers) + archive.close() + + +.. datafile:: numbers.txt + :cols: 20 + :rows: 10 + :edit: + + +.. activecode:: ac_l23_1a_en + :nocodelens: + :datafile: numbers.txt + :enabledownload: + + Try the previous program: + + ~~~~ + archive = open("numbers.txt", "w") + for numbers in range(1, 31): + archive.write("%d\n" % numbers) + archive.close() + + + ==== + print("Data has been written to the file numbers.txt") + + ++ When executing the previous program, the file `numbers.txt` is modified. ++ The `w` mode creates the file if it does not exist, if it exists it will be deleted and rewritten. + + +.. activecode:: ac_l23_1b_en + :nocodelens: + :datafile: numbers.txt + :enabledownload: + + You have already written to the file ``"numbers.txt"``. Now you are going to read the data you have written: + + ~~~~ + archive = open("numbers.txt", "r") + for line in archive.readlines(): + print(line) + archive.close() + ++ `readlines()` generates a list where each element is a read line. ++ The `numbers.txt` file now has written numbers, each number on a different line. + This line break was written with the special character `\n`. ++ If we want to remove this character from the end, we can use `print(line.rstrip())`. + Try to print the text lines in this way. + + +Pythonic way +------------ + +.. code-block:: python + + with open("numbers.txt", "r") as f: + print(f.read()) + +.. activecode:: ac_l23_1c_en + :nocodelens: + :datafile: numbers.txt + :enabledownload: + + with open("numbers.txt", "r") as f: + print(f.read()) + + ++ The previous code does the same as the Pythonic way. ++ In the previous slide we saw how normal programmers read ++ Python is great because you can always go deeper ++ Python is simple, but hard to exhaust \ No newline at end of file diff --git a/293/_sources/lectures/TWP23/TWP23_2.rst.txt b/293/_sources/lectures/TWP23/TWP23_2.rst.txt new file mode 100644 index 0000000000..f3fb9799e1 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_2.rst.txt @@ -0,0 +1,98 @@ +Crypto +====== + + +.. datafile:: mensaje.txt + :hide: + + Éste es el archivo de texto + que usted está modificando + para que todas las vocales + sean cambiadas por "*". + + +.. activecode:: ac_l23_2a + :nocodelens: + :datafile: mensaje.txt, crypto.txt + + Lea el archivo ``"mensaje.txt"`` y escriba el archivo ``"crypto.txt"`` el cual + debe tener el mismo texto del primer archivo, pero con las vocales cambiadas por + ``"*"``. + + ~~~~ + texto = open("mensaje.txt", "r") + salida = open("crypto.txt", "w") + + for linea in texto.readlines(): + for letra in linea: + if letra in "aeiou": + salida.write("*") + else: + salida.write(letra) + + texto.close() + salida.close() + + + ==== + print("Se han escrito datos en el archivo crypto.txt") + + +.. datafile:: crypto.txt + :cols: 20 + :rows: 10 + :edit: + + +Ejercicio +--------- + +.. activecode:: ac_l23_2b + :nocodelens: + :datafile: mensaje.txt, crypto.txt + + Como puede observar, el código anterior no cambió algunas vocales + del archivo ``"mensaje.txt"``. Esto debido a las mayúsculas o a los acentos. + Su trabajo es modificar el programa anterior para que cambie **TODAS** las + vocales por ``"*"``. **Recuerde**: el método ``.lower()`` devuelve una cadena + con todos sus caracteres vueltos letras minúsculas. Esta vez, va a escribir en + el archivo ``"crypto2.txt"`` + + ~~~~ + texto = open("mensaje.txt", "r") + salida = open("crypto2.txt", "w") + + # Modifique el programa + + for linea in texto.readlines(): + for letra in linea: + if letra in "aeiou": + salida.write("*") + else: + salida.write(letra) + + texto.close() + salida.close() + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + archivo = open("crypto2.txt", "r") + text = """*st* *s *l *rch*v* d* t*xt* q** *st*d *st* m*d*f*c*nd* p*r* q** t*d*s l*s v*c*l*s s**n c*mb**d*s p*r "*".""" + + self.assertEqual(archivo.read().replace("\n", " ").rstrip(), text.strip(), f"Esperado: {text}") + + + print("Se han escrito datos en el archivo crypto2.txt") + + myTests().main() + + +.. datafile:: crypto2.txt + :cols: 20 + :rows: 10 + :edit: diff --git a/293/_sources/lectures/TWP23/TWP23_2_en.rst.txt b/293/_sources/lectures/TWP23/TWP23_2_en.rst.txt new file mode 100644 index 0000000000..f17738723e --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_2_en.rst.txt @@ -0,0 +1,99 @@ +Crypto +====== + + +.. datafile:: message.txt + :hide: + + This is the text file + you are modifying + so that all vowels + are changed to "*". + + +.. activecode:: ac_l23_2a_en + :nocodelens: + :datafile: message.txt, crypto_en.txt + + Read the file ``"message.txt"`` and write the file ``" crypto_en.txt"`` which + should have the same text as the first file, but with vowels replaced by + ``"*"``. + + ~~~~ + text = open("message.txt", "r") + output = open(" crypto_en.txt", "w") + + for line in text.readlines(): + for letter in line: + if letter in "aeiouAEIOU": + output.write("*") + else: + output.write(letter) + + text.close() + output.close() + + + ==== + print("Data has been written to the file crypto_en.txt") + + +.. datafile:: crypto_en.txt + :cols: 20 + :rows: 10 + :edit: + + +Exercise +--------- + +.. activecode:: ac_l23_2b_en + :nocodelens: + :datafile: message.txt, crypto_en.txt + + As you can see, the previous code did not change some vowels + in the file ``"message.txt"``. This is due to capital letters or accents. + Your task is to modify the previous program so that it changes **ALL** vowels + to ``"*"``. **Remember**: the ``.lower()`` method returns a string + with all its characters turned into lowercase letters. This time, you will write to + the file ``" crypto2_en.txt"``. + + ~~~~ + text = open("message.txt", "r") + output = open(" crypto2_en.txt", "w") + + # Modify the program + + for line in text.readlines(): + for letter in line: + if letter in "aeiou": + output.write("*") + else: + output.write(letter) + + text.close() + output.close() + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + file = open(" crypto2_en.txt", "r") + text = """th*s *s th* t*xt f*l* y** *r* m*d*fy*ng s* th*t *ll v*w*ls *r* ch*ng*d t* "*". + """ + + self.assertEqual(file.read().replace("\n", " ").rstrip(), text.strip(), f"Expected: {text}") + + + print("Data has been written to the file crypto2_en.txt") + + myTests().main() + + +.. datafile:: crypto2_en.txt + :cols: 20 + :rows: 10 + :edit: \ No newline at end of file diff --git a/293/_sources/lectures/TWP23/TWP23_3.rst.txt b/293/_sources/lectures/TWP23/TWP23_3.rst.txt new file mode 100644 index 0000000000..37a3689950 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_3.rst.txt @@ -0,0 +1,61 @@ +Validar dirección IP +==================== + +.. datafile:: IPS.txt + :cols: 20 + :rows: 12 + + 200.135.80.9 + 192.168.1.1 + 8.35.67.74 + 257.32.4.5 + 85.345.1.2 + 1.2.3.4 + 9.8.284.5 + 192.168.0.256 + + +.. activecode:: ac_l23_3 + :nocodelens: + :datafile: Validos.txt, Invalidos.txt + + def ip_ok(ip): + ip = ip.split(".") + for byte in ip: + if int(byte) > 255: + return False + return True + + + ips = open("IPS.txt") + validos = open("Validos.txt", "w") + invalidos = open("Invalidos.txt", "w") + for linea in ips.readlines(): + if ip_ok(linea): + validos.write(linea) + else: + invalidos.write(linea) + + ips.close() + validos.close() + invalidos.close() + + + ==== + print("Se han escrito datos en los archivos Validos.txt e Invalidos.txt") + + +.. datafile:: Validos.txt + :edit: + :cols: 15 + :rows: 7 + + Válidos + + +.. datafile:: Invalidos.txt + :edit: + :cols: 15 + :rows: 7 + + Inválidos diff --git a/293/_sources/lectures/TWP23/TWP23_3_en.rst.txt b/293/_sources/lectures/TWP23/TWP23_3_en.rst.txt new file mode 100644 index 0000000000..3ea2a3c62f --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_3_en.rst.txt @@ -0,0 +1,61 @@ +Validate IP Address +==================== + +.. datafile:: IPS_en.txt + :cols: 20 + :rows: 12 + + 200.135.80.9 + 192.168.1.1 + 8.35.67.74 + 257.32.4.5 + 85.345.1.2 + 1.2.3.4 + 9.8.284.5 + 192.168.0.256 + + +.. activecode:: ac_l23_3_en + :nocodelens: + :datafile: valid.txt, Invalid.txt + + def ip_ok(ip): + ip = ip.split(".") + for byte in ip: + if int(byte) > 255: + return False + return True + + + ips = open("IPS_en.txt") + validos = open("valid.txt", "w") + invalidos = open("Invalid.txt", "w") + for linea in ips.readlines(): + if ip_ok(linea): + validos.write(linea) + else: + invalidos.write(linea) + + ips.close() + validos.close() + invalidos.close() + + + ==== + print("Data has been written in the valid.txt and Invalid.txt files") + + +.. datafile:: valid.txt + :edit: + :cols: 15 + :rows: 7 + + Valid + + +.. datafile:: Invalid.txt + :edit: + :cols: 15 + :rows: 7 + + Invalid \ No newline at end of file diff --git a/293/_sources/lectures/TWP23/TWP23_4.rst.txt b/293/_sources/lectures/TWP23/TWP23_4.rst.txt new file mode 100644 index 0000000000..ce6e347323 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_4.rst.txt @@ -0,0 +1,59 @@ +HTML +==== + ++ Las páginas web están escritas en HTML (lenguaje de marcado de hipertexto) ++ Las etiquetas HTML comienzan con ++ La página web está escrita entre y , que es la etiqueta más grande nivel ++ Normalmente insertamos código javascript ++ Javascript no es un subconjunto de Java + + +.. code-block:: python + + archivo = open("hola.html", "w") + archivo.write( + """ + + + + Título de la Pagina + + + Hola! + + """ + ) + archivo.close() + + +.. activecode:: ac_l23_4 + :nocodelens: + :datafile: hola.html + + Pruebe el programa anterior. + + ~~~~ + archivo = open("hola.html", "w") + archivo.write( + """ + + + + Título de la Página + + + Hola! + + """ + ) + archivo.close() + + + ==== + print("Se han escrito datos en el archivo hola.html") + + +.. datafile:: hola.html + :edit: + :cols: 40 + :rows: 12 diff --git a/293/_sources/lectures/TWP23/TWP23_4_en.rst.txt b/293/_sources/lectures/TWP23/TWP23_4_en.rst.txt new file mode 100644 index 0000000000..b4c0ce4db3 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_4_en.rst.txt @@ -0,0 +1,59 @@ +HTML +==== + ++ Web pages are written in HTML (Hypertext Markup Language). ++ HTML tags begin with < and end with >. ++ The web page is written between and , which is the top-level tag. ++ We usually insert JavaScript code. ++ JavaScript is not a subset of Java. + + +.. code-block:: python + + file = open("hello.html", "w") + file.write( + """ + + + + Page Title + + + Hello! + + """ + ) + file.close() + + +.. activecode:: ac_l23_4_en + :nocodelens: + :datafile: hello.html + + Test the program above. + + ~~~~ + file = open("hello.html", "w") + file.write( + """ + + + + Page Title + + + Hello! + + """ + ) + file.close() + + + ==== + print("Data has been written to the file hello.html") + + +.. datafile:: hello.html + :edit: + :cols: 40 + :rows: 12 \ No newline at end of file diff --git a/293/_sources/lectures/TWP23/TWP23_5.rst.txt b/293/_sources/lectures/TWP23/TWP23_5.rst.txt new file mode 100644 index 0000000000..0b2d5b1be6 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_5.rst.txt @@ -0,0 +1,48 @@ +Diccionarios +============ + + ++ El diccionario en sí consiste en relacionar una clave con un valor específico ++ A diferencia de las listas, donde el índice es un número, los diccionarios usar sus claves como índice ++ Para agregar nuevos elementos que no necesito agregar, solo haga la sesión + + + Si la clave ya existe: el valor asociado cambia + + Si la clave no existe: se agrega la nueva clave + +.. codelens:: cl_l23_5a + + d = {} + d["a"] = "alpha" + d["o"] = "omega" + d["g"] = "gama" + print(d) + print(d["a"]) + + +.. activecode:: ac_l23_5 + :nocodelens: + :stdin: + + d = {} + d["a"] = "alpha" + d["o"] = "omega" + d["g"] = "gama" + print(d) + + + # Esta línea va a resultar en error porque no hay + # una clave "x" en el diccionario + print(d["x"]) + +.. codelens:: cl_l23_5b + + d = {} + d["a"] = "alpha" + d["o"] = "omega" + d["g"] = "gama" + print(d.keys()) + print(d.values()) + print("g" in d) + print("x" in d) + for clave in d: + print(clave) diff --git a/293/_sources/lectures/TWP23/TWP23_5_en.rst.txt b/293/_sources/lectures/TWP23/TWP23_5_en.rst.txt new file mode 100644 index 0000000000..2c055d349a --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_5_en.rst.txt @@ -0,0 +1,48 @@ +Dictionaries +============ + + ++ The dictionary itself consists of relating a key with a specific value ++ Unlike lists, where the index is a number, dictionaries use their keys as index ++ To add new elements that I don't need to add, just make the session + + + If the key already exists: the associated value changes + + If the key does not exist: the new key is added + +.. codelens:: cl_l23_5a_en + + d = {} + d["a"] = "alpha" + d["o"] = "omega" + d["g"] = "gamma" + print(d) + print(d["a"]) + + +.. activecode:: ac_l23_5_en + :nocodelens: + :stdin: + + d = {} + d["a"] = "alpha" + d["o"] = "omega" + d["g"] = "gamma" + print(d) + + + # This line will result in an error because there is no + # a "x" key in the dictionary + print(d["x"]) + +.. codelens:: cl_l23_5b_en + + d = {} + d["a"] = "alpha" + d["o"] = "omega" + d["g"] = "gamma" + print(d.keys()) + print(d.values()) + print("g" in d) + print("x" in d) + for key in d: + print(key) \ No newline at end of file diff --git a/293/_sources/lectures/TWP23/TWP23_6.rst.txt b/293/_sources/lectures/TWP23/TWP23_6.rst.txt new file mode 100644 index 0000000000..2b7f8ae6f9 --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_6.rst.txt @@ -0,0 +1,47 @@ +Último Ejercicio +================ + + +.. datafile:: alice_archivo.txt + :fromfile: ../_static/alice.txt + :hide: + + +.. activecode:: ac_l23_6 + :nocodelens: + :available_files: alice_archivo.txt + :Language: python + + Haga un programa que lea el archivo ``alice_archivo.txt`` y cuente el número de ocurrencias de cada palabra en el texto. Nota: + para conocer los caracteres especiales use ``import string`` y use ``string.punctuation``. + + ~~~~ + import string + + archivo = open("alice_archivo.txt", "r") + texto = archivo.read() + texto = texto.lower() + + for c in string.punctuation: + texto = texto.replace(c, " ") + texto = texto.split() + + dic = {} + for palabra in texto: + if palabra not in dic: + dic[palabra] = 1 + else: + dic[palabra] += 1 + + print("Aparece Alice %s veces" % dic["alice"]) + archivo.close() + + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + + +“La vida es como andar en bicicleta. Para mantener el equilibrio, debes seguir moviéndote”. - Einstein diff --git a/293/_sources/lectures/TWP23/TWP23_6_en.rst.txt b/293/_sources/lectures/TWP23/TWP23_6_en.rst.txt new file mode 100644 index 0000000000..067f08aada --- /dev/null +++ b/293/_sources/lectures/TWP23/TWP23_6_en.rst.txt @@ -0,0 +1,47 @@ +Last Exercise +============= + + +.. datafile:: alice_file.txt + :fromfile: ../_static/alice.txt + :hide: + + +.. activecode:: ac_l23_6_en + :nocodelens: + :available_files: alice_file.txt + :Language: python + + Create a program that reads the file ``alice_file.txt`` and counts the number of occurrences of each word in the text. Note: + to remove special characters, use ``import string`` and ``string.punctuation``. + + ~~~~ + import string + + file = open("alice_file.txt", "r") + text = file.read() + text = text.lower() + + for c in string.punctuation: + text = text.replace(c, " ") + text = text.split() + + dic = {} + for word in text: + if word not in dic: + dic[word] = 1 + else: + dic[word] += 1 + + print("Alice appears %s times" % dic["alice"]) + file.close() + + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + + +“Life is like riding a bicycle. To keep your balance, you must keep moving.” - Einstein \ No newline at end of file diff --git a/293/_sources/lectures/TWP23/toctree.rst.txt b/293/_sources/lectures/TWP23/toctree.rst.txt new file mode 100644 index 0000000000..b0827d4bb4 --- /dev/null +++ b/293/_sources/lectures/TWP23/toctree.rst.txt @@ -0,0 +1,23 @@ +======================= +Archivos y diccionarios +======================= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP23_1.rst + TWP23_2.rst + TWP23_3.rst + TWP23_4.rst + TWP23_5.rst + TWP23_6.rst diff --git a/293/_sources/lectures/TWP23/toctree_en.rst.txt b/293/_sources/lectures/TWP23/toctree_en.rst.txt new file mode 100644 index 0000000000..2100ba8e69 --- /dev/null +++ b/293/_sources/lectures/TWP23/toctree_en.rst.txt @@ -0,0 +1,23 @@ +======================= +Files and dictionaries +======================= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP23_1_en.rst + TWP23_2_en.rst + TWP23_3_en.rst + TWP23_4_en.rst + TWP23_5_en.rst + TWP23_6_en.rst diff --git a/293/_sources/lectures/TWP25/TWP25_1.rst.txt b/293/_sources/lectures/TWP25/TWP25_1.rst.txt new file mode 100644 index 0000000000..468977f35a --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_1.rst.txt @@ -0,0 +1,53 @@ +Clases y objetos +================= + ++ Las clases asocian datos (atributos) y operaciones (métodos) en una estructura. ++ Un objeto es una variable cuyo tipo es una clase, es decir, un objeto es una instancia de una clase. ++ Solo veremos los conceptos básicos de la programación orientada a objetos. + +.. codelens:: cl_l25_1a + + class Television: + def __init__(self): + self.conectado = False + self.canal = 2 + + + tv_cuarto = Television() + tv_sala = Television() + print(tv_cuarto.conectado) + print(tv_cuarto.canal) + tv_sala.conectado = True + tv_sala.canal = 5 + print(tv_sala.conectado) + print(tv_sala.canal) + ++ Cuando declaramos una clase, estamos creando un nuevo tipo de datos. ++ Al igual que cuando creamos una lista o una cadena, estamos creando instancias o creando una instancia de estas clases. ++ Es lo mismo hacer ``list = []`` o ``list = list ()`` ++ El método ``__init__`` se llama constructor y se llama al crear el objeto. ++ El parámetro ``self`` significa el objeto de televisión en sí. ++ ``self.conectado`` es un valor del objeto ``television``. ++ Siempre que queramos crear atributos de un objeto, debemos asociarlos con uno mismo utilizando ``self``. ++ De lo contrario, si escribimos solamente ``conectado = False``, ``conectado`` sería solo una variable local del método y no un atributo. + +.. codelens:: cl_l25_1b + + class Television: + def __init__(self): + self.conectado = False + self.canal = 2 + + def cambiar_canal_hacia_abajo(self): + self.canal -= 1 + + def cambiar_canal_hacia_arriba(self): + self.canal += 1 + + + tv = Television() + tv.cambiar_canal_hacia_arriba() + tv.cambiar_canal_hacia_arriba() + print(tv.canal) + tv.cambiar_canal_hacia_abajo() + print(tv.canal) diff --git a/293/_sources/lectures/TWP25/TWP25_1_en.rst.txt b/293/_sources/lectures/TWP25/TWP25_1_en.rst.txt new file mode 100644 index 0000000000..566adcfabc --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_1_en.rst.txt @@ -0,0 +1,53 @@ +Classes and objects +=================== + ++ Classes combine data (attributes) and operations (methods) in a structure. ++ An object is a variable whose type is a class, that is, an object is an instance of a class. ++ We will only see the basic concepts of object-oriented programming. + +.. codelens:: cl_l25_1a_en + + class Television: + def __init__(self): + self.connected = False + self.channel = 2 + + + room_tv = Television() + living_room_tv = Television() + print(room_tv.connected) + print(room_tv.channel) + living_room_tv.connected = True + living_room_tv.channel = 5 + print(living_room_tv.connected) + print(living_room_tv.channel) + ++ When we declare a class, we are creating a new data type. ++ Just like when we create a list or a string, we are creating instances or creating an instance of these classes. ++ It is the same to do ``list = []`` or ``list = list()``. ++ The ``__init__`` method is called constructor and is called when creating the object. ++ The parameter ``self`` means the television object itself. ++ ``self.connected`` is a value of the ``television`` object. ++ Whenever we want to create attributes of an object, we must associate them with itself using ``self``. ++ Otherwise, if we only write ``connected = False``, ``connected`` would be just a local variable of the method and not an attribute. + +.. codelens:: cl_l25_1b_en + + class Television: + def __init__(self): + self.connected = False + self.channel = 2 + + def change_channel_down(self): + self.channel -= 1 + + def change_channel_up(self): + self.channel += 1 + + + tv = Television() + tv.change_channel_up() + tv.change_channel_up() + print(tv.channel) + tv.change_channel_down() + print(tv.channel) \ No newline at end of file diff --git a/293/_sources/lectures/TWP25/TWP25_2.rst.txt b/293/_sources/lectures/TWP25/TWP25_2.rst.txt new file mode 100644 index 0000000000..21485766b8 --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_2.rst.txt @@ -0,0 +1,54 @@ +Clase Cliente y Clase Cuenta +============================ + ++ Automatizarás el banco TATU, controlando el saldo de las cuentas corriente. ++ Cada cuenta corriente puede tener uno o más clientes como titular. ++ El banco controla solo el nombre y el número de teléfono. ++ La cuenta corriente muestra un saldo y un estado de cuenta de las operaciones de retiro y depósito. ++ No hay cuentas especiales, por lo que el cliente no puede retirar más de lo que tiene de saldo. + +.. activecode:: ac_l25_2a + :nocodelens: + :stdin: + + class Cliente: + def __init__(self, nombre, telefono): + self.nombre = nombre + self.telefono = telefono + + class Cuenta: + def __init__(self, clientes, numero, saldo=0): + self.saldo = saldo + self.clientes = clientes + self.numero = numero + + def resumen(self): + print("CC numero: %s saldo: %10.2f" % (self.numero, self.saldo)) + + def retirar(self, monto): + if self.saldo >= monto: + self.saldo -= monto + else: + print("Saldo insuficiente para retirar") + + def depositar(self, monto): + self.saldo += monto + + +Utilizando las clases Cliente y Cuenta +-------------------------------------- + +.. activecode:: ac_l25_2b + :nocodelens: + :stdin: + :include: ac_l25_2a + + juan = Cliente("Juan de Silva", "777-1234") + maria = Cliente("Maria de Silva", "555-4321") + print("nombre : %s. telefono: %s" % (juan.nombre, juan.telefono)) + print("nombre : %s. telefono: %s" % (maria.nombre, maria.telefono)) + + cuenta_1 = Cuenta([juan], 1, 1000) + cuenta_2 = Cuenta([maria, juan], 2, 500) + cuenta_1.resumen() + cuenta_2.resumen() diff --git a/293/_sources/lectures/TWP25/TWP25_2_en.rst.txt b/293/_sources/lectures/TWP25/TWP25_2_en.rst.txt new file mode 100644 index 0000000000..7a774faaaa --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_2_en.rst.txt @@ -0,0 +1,54 @@ +Class Client and Class Account +============================== + ++ You will automate the TATU bank, controlling the balance of checking accounts. ++ Each checking account can have one or more clients as holders. ++ The bank only controls the name and phone number. ++ The checking account shows a balance and a statement of withdrawal and deposit operations. ++ There are no special accounts, so the client cannot withdraw more than they have in balance. + +.. activecode:: ac_l25_2a_en + :nocodelens: + :stdin: + + class Cliente: + def __init__(self, nombre, telefono): + self.nombre = nombre + self.telefono = telefono + + class Cuenta: + def __init__(self, clientes, numero, saldo=0): + self.saldo = saldo + self.clientes = clientes + self.numero = numero + + def resumen(self): + print("CC number: %s balance: %10.2f" % (self.numero, self.saldo)) + + def retirar(self, monto): + if self.saldo >= monto: + self.saldo -= monto + else: + print("Insufficient balance to withdraw") + + def depositar(self, monto): + self.saldo += monto + + +Using the Client and Account classes +------------------------------------ + +.. activecode:: ac_l25_2b_en + :nocodelens: + :stdin: + :include: ac_l25_2a + + juan = Cliente("Juan de Silva", "777-1234") + maria = Cliente("Maria de Silva", "555-4321") + print("name: %s. phone: %s" % (juan.nombre, juan.telefono)) + print("name: %s. phone: %s" % (maria.nombre, maria.telefono)) + + account_1 = Cuenta([juan], 1, 1000) + account_2 = Cuenta([maria, juan], 2, 500) + account_1.resumen() + account_2.resumen() \ No newline at end of file diff --git a/293/_sources/lectures/TWP25/TWP25_3.rst.txt b/293/_sources/lectures/TWP25/TWP25_3.rst.txt new file mode 100644 index 0000000000..94ef6e45d7 --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_3.rst.txt @@ -0,0 +1,133 @@ +Declaración de operaciones y herencia +===================================== + ++ Agregue el método ``estado_de_cuenta`` a la clase ``Cuenta`` el cual imprime una lista de las operaciones de retiro y depósito realizadas. ++ Cambie el método ``__init__`` para usar el método ``depositar`` para inicializar el saldo. + + +Clase Cliente y Clase Cuenta (Mejorada) +--------------------------------------- + +.. activecode:: ac_l25_3a + :nocodelens: + :stdin: + + class Cliente: + def __init__(self, nombre, telefono): + self.nombre = nombre + self.telefono = telefono + + + class Cuenta: + def __init__(self, clientes, numero, saldo=0): + self.saldo = 0 + self.clientes = clientes + self.numero = numero + self.operaciones = [] + self.depositar(saldo) + + def resumen(self): + print("CC numero: %s saldo: %10.2f" % (self.numero, self.saldo)) + + def retirar(self, monto): + if self.saldo >= monto: + self.saldo -= monto + self.operaciones.append(["Retiro", monto]) + else: + print("Saldo insuficiente para retirar") + + def depositar(self, monto): + self.saldo += monto + self.operaciones.append(["Depósito", monto]) + + def estado_de_cuenta(self): + print("extracto CC N %s" % self.numero) + for op in self.operaciones: + print("%10s %10.2f" % (op[0], op[1])) + print("%10s %10.2f\n" % ("Saldo", self.saldo)) + + +Utilizando las clases Cliente y Cuenta (Mejorada) +************************************************* + +.. activecode:: ac_l25_3b + :nocodelens: + :stdin: + :include: ac_l25_3a + + juan = Cliente("Juan de Silva", "777-1234") + maria = Cliente("Maria de Silva", "555-4321") + cuenta_1 = Cuenta([juan], 1, 1000) + cuenta_2 = Cuenta([maria, juan], 2, 500) + + cuenta_1.retirar(50) + cuenta_2.depositar(300) + cuenta_1.retirar(190) + cuenta_2.depositar(95.15) + cuenta_2.retirar(250) + + cuenta_1.estado_de_cuenta() + cuenta_2.estado_de_cuenta() + +Herencia +-------- + ++ La herencia en objetos permite modificar nuestras clases, agregando o modificando atributos y métodos, basados en la clase anterior. ++ Vamos a crear cuentas especiales, donde podemos retirar más dinero que el saldo, hasta cierto límite. ++ Las operaciones de depósito, retiro y resumen continúan como una cuenta normal. + + +Clase Cuenta Especial +--------------------- + +.. activecode:: ac_l25_3c + :nocodelens: + :stdin: + :include: ac_l25_3a + + class CuentaEspecial(Cuenta): + def __init__(self, clientes, numero, saldo=0, limite=0): + Cuenta.__init__(self, clientes, numero, saldo) + self.limite = limite + + def retirar(self, monto): + if self.saldo + self.limite >= monto: + self.saldo -= monto + self.operaciones.append(["Retiro", monto]) + else: + print("Saldo insuficiente para retirar") + + ++ Tenga en cuenta que escribimos ``Cuenta`` entre paréntesis. ++ ``CuentaEspecial`` hereda los métodos y atributos de ``Cuenta``. ++ ``self.limite`` se creará solo para clases de tipo ``CuentaEspecial``. ++ Tenga en cuenta que estamos sobre escribiendo completamente el método ``retirar`` en ``CuentaEspecial``. + +Ventajas de la herencia +----------------------- + ++ Hemos modificado muy poco nuestro programa, manteniendo la funcionalidad anterior y agregando nuevas características. ++ Fue posible reutilizar los métodos de la cuenta. ++ Por lo tanto, la definición de la clase ``CuentaEspecial`` fue mucho más simple, incluyendo solo el comportamiento diferente. + +Utilizando todas las clases +--------------------------- + +.. activecode:: ac_l25_3d + :nocodelens: + :stdin: + :include: ac_l25_3a, ac_l25_3c + + juan = Cliente("Juan de Silva", "777-1234") + maria = Cliente("Maria de Silva", "555-4321") + cuenta_1 = Cuenta([juan], 1, 1000) + cuenta_2 = CuentaEspecial([maria, juan], 2, 500, 1000) + + cuenta_1.retirar(50) + cuenta_2.depositar(300) + cuenta_1.retirar(190) + cuenta_2.depositar(95.15) + cuenta_2.retirar(1500) + + cuenta_1.estado_de_cuenta() + cuenta_2.estado_de_cuenta() diff --git a/293/_sources/lectures/TWP25/TWP25_3_en.rst.txt b/293/_sources/lectures/TWP25/TWP25_3_en.rst.txt new file mode 100644 index 0000000000..01eac41061 --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_3_en.rst.txt @@ -0,0 +1,133 @@ +Operations declaration and inheritance +====================================== + ++ Add the method ``statement`` to the ``Account`` class that prints a list of deposit and withdrawal operations. ++ Change the ``__init__`` method to use the ``deposit`` method to initialize the balance. + + +Client Class and Improved Account Class +--------------------------------------- + +.. activecode:: ac_l25_3a_en + :nocodelens: + :stdin: + + class Client: + def __init__(self, name, phone): + self.name = name + self.phone = phone + + + class Account: + def __init__(self, clients, number, balance=0): + self.balance = 0 + self.clients = clients + self.number = number + self.operations = [] + self.deposit(balance) + + def summary(self): + print("Account number: %s \nBalance: %10.2f" % (self.number, self.balance)) + + def withdraw(self, amount): + if self.balance >= amount: + self.balance -= amount + self.operations.append(["Withdrawal", amount]) + else: + print("Not enough funds for withdrawal") + + def deposit(self, amount): + self.balance += amount + self.operations.append(["Deposit", amount]) + + def statement(self): + print("Account Statement %s" % self.number) + for op in self.operations: + print("%10s %10.2f" % (op[0], op[1])) + print("%10s %10.2f\n" % ("Balance", self.balance)) + + +Using the Client and Improved Account Classes +************************************************* + +.. activecode:: ac_l25_3b_en + :nocodelens: + :stdin: + :include: ac_l25_3a + + juan = Client("Juan de Silva", "777-1234") + maria = Client("Maria de Silva", "555-4321") + account_1 = Account([juan], 1, 1000) + account_2 = Account([maria, juan], 2, 500) + + account_1.withdraw(50) + account_2.deposit(300) + account_1.withdraw(190) + account_2.deposit(95.15) + account_2.withdraw(250) + + account_1.statement() + account_2.statement() + +Inheritance +----------- + ++ Object inheritance allows us to modify our classes by adding or modifying attributes and methods based on the previous class. ++ We will create special accounts where we can withdraw more money than the balance, up to a certain limit. ++ Deposit, withdrawal, and summary operations continue as a regular account. + + +Special Account Class +--------------------- + +.. activecode:: ac_l25_3c_en + :nocodelens: + :stdin: + :include: ac_l25_3a + + class SpecialAccount(Account): + def __init__(self, clients, number, balance=0, limit=0): + Account.__init__(self, clients, number, balance) + self.limit = limit + + def withdraw(self, amount): + if self.balance + self.limit >= amount: + self.balance -= amount + self.operations.append(["Withdrawal", amount]) + else: + print("Not enough funds for withdrawal") + + ++ Note that we wrote ``Account`` in parentheses. ++ ``SpecialAccount`` inherits the methods and attributes of ``Account``. ++ ``self.limit`` will only be created for classes of type ``SpecialAccount``. ++ Note that we are completely overriding the ``withdraw`` method in ``SpecialAccount``. + +Advantages of Inheritance +------------------------- + ++ We have made minimal changes to our program, maintaining previous functionality and adding new features. ++ It was possible to reuse account methods. ++ Therefore, the definition of the ``SpecialAccount`` class was much simpler, including only the different behavior. + +Using all classes +----------------- + +.. activecode:: ac_l25_3d_en + :nocodelens: + :stdin: + :include: ac_l25_3a, ac_l25_3c + + juan = Client("Juan de Silva", "777-1234") + maria = Client("Maria de Silva", "555-4321") + account_1 = Account([juan], 1, 1000) + account_2 = SpecialAccount([maria, juan], 2, 500, 1000) + + account_1.withdraw(50) + account_2.deposit(300) + account_1.withdraw(190) + account_2.deposit(95.15) + account_2.withdraw(1500) + + account_1.statement() + account_2.statement() \ No newline at end of file diff --git a/293/_sources/lectures/TWP25/TWP25_4.rst.txt b/293/_sources/lectures/TWP25/TWP25_4.rst.txt new file mode 100644 index 0000000000..f3e9572885 --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_4.rst.txt @@ -0,0 +1,37 @@ +Otros ejemplos de POO +===================== + ++ Podemos crear una clase ``Persona`` con los atributos básicos. + +.. activecode:: ac_l25_4a + :nocodelens: + :stdin: + + import datetime + + + class Persona: + def __init__(self, nombre, nacimiento): + self.nombre = nombre + self.nacimiento = nacimiento + + def edad(self): + delta = datetime.date.today() - self.nacimiento + return int(delta.days / 365) + + def __str__(self): + return "%s, %d años" % (self.nombre, self.edad()) + + + masanori = Persona("Fernando Masanori", datetime.date(1980, 9, 1)) + print(masanori.edad()) + print(masanori) + ++ Puedes utilizar la implementación de la clase ``Persona`` para crear un objeto con tu nombre. + +.. activecode:: ac_l25_4b + :nocodelens: + :stdin: + :include: ac_l25_4a + + # Crea un objeto con tu nombre diff --git a/293/_sources/lectures/TWP25/TWP25_4_en.rst.txt b/293/_sources/lectures/TWP25/TWP25_4_en.rst.txt new file mode 100644 index 0000000000..7f310d4e7c --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_4_en.rst.txt @@ -0,0 +1,37 @@ +Other examples of OOP +===================== + ++ We can create a class ``Person`` with basic attributes. + +.. activecode:: ac_l25_4a_en + :nocodelens: + :stdin: + + import datetime + + + class Person: + def __init__(self, name, birthdate): + self.name = name + self.birthdate = birthdate + + def age(self): + delta = datetime.date.today() - self.birthdate + return int(delta.days / 365) + + def __str__(self): + return "%s, %d years old" % (self.name, self.age()) + + + masanori = Person("Fernando Masanori", datetime.date(1980, 9, 1)) + print(masanori.age()) + print(masanori) + ++ You can use the implementation of the class ``Person`` to create an object with your name. + +.. activecode:: ac_l25_4b_en + :nocodelens: + :stdin: + :include: ac_l25_4a + + # Create an object with your name \ No newline at end of file diff --git a/293/_sources/lectures/TWP25/TWP25_5.rst.txt b/293/_sources/lectures/TWP25/TWP25_5.rst.txt new file mode 100644 index 0000000000..4a6d2d593d --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_5.rst.txt @@ -0,0 +1,51 @@ +Múltiple herencia y ¿Qué objeto es? +=================================== + ++ Se puede heredar de varias clases. ++ Pueden existir momentos en que quieras verificar el tipo de una instancia. ++ En Python existe la función ``isinstance``. ++ Permite verificar si una instancia de una clase es realmente de una clase dada. + +.. codelens:: cl_l25_5 + + class Ethernet: + def __init__(self, nombre, direccion_mac): + self.nombre = nombre + self.direccion_mac = direccion_mac + + + class Wireless(Ethernet): + def __init__(self, nombre, direccion_mac): + Ethernet.__init__(self, nombre, direccion_mac) + + + class PCI: + def __init__(self, bus, fabricante): + self.bus = bus + self.fabricante = fabricante + + + class USB: + def __init__(self, dispositivo): + self.dispositivo = dispositivo + + + class PCIEthernet(PCI, Ethernet): + def __init__(self, bus, fabricante, nombre, direccion_mac): + PCI.__init__(self, bus, fabricante) + Ethernet.__init__(self, nombre, direccion_mac) + + + class USBWireless(USB, Wireless): + def __init__(self, dispotivo, nombre, direccion_mac): + USB.__init__(self, dispotivo) + Wireless.__init__(self, nombre, direccion_mac) + + + wlan0 = USBWireless("usb0", "wlan0", "00:33:44:55:66") + eth0 = PCIEthernet("pci :0:0:1", "realtek", "eth0", "00:11:22:33:44") + + + print(isinstance(wlan0, Ethernet)) + print(isinstance(eth0, PCI)) + print(isinstance(eth0, USB)) diff --git a/293/_sources/lectures/TWP25/TWP25_5_en.rst.txt b/293/_sources/lectures/TWP25/TWP25_5_en.rst.txt new file mode 100644 index 0000000000..3fc828749f --- /dev/null +++ b/293/_sources/lectures/TWP25/TWP25_5_en.rst.txt @@ -0,0 +1,51 @@ +Multiple Inheritance and What Object is It? +============================================ + ++ Multiple inheritance is possible. ++ There may be times when you want to check the type of an instance. ++ Python has the ``isinstance`` function. ++ It allows you to check if an instance of a class is actually of a given class. + +.. codelens:: cl_l25_5_en + + class Ethernet: + def __init__(self, name, mac_address): + self.name = name + self.mac_address = mac_address + + + class Wireless(Ethernet): + def __init__(self, name, mac_address): + Ethernet.__init__(self, name, mac_address) + + + class PCI: + def __init__(self, bus, manufacturer): + self.bus = bus + self.manufacturer = manufacturer + + + class USB: + def __init__(self, device): + self.device = device + + + class PCIEthernet(PCI, Ethernet): + def __init__(self, bus, manufacturer, name, mac_address): + PCI.__init__(self, bus, manufacturer) + Ethernet.__init__(self, name, mac_address) + + + class USBWireless(USB, Wireless): + def __init__(self, device, name, mac_address): + USB.__init__(self, device) + Wireless.__init__(self, name, mac_address) + + + wlan0 = USBWireless("usb0", "wlan0", "00:33:44:55:66") + eth0 = PCIEthernet("pci :0:0:1", "realtek", "eth0", "00:11:22:33:44") + + + print(isinstance(wlan0, Ethernet)) + print(isinstance(eth0, PCI)) + print(isinstance(eth0, USB)) \ No newline at end of file diff --git a/293/_sources/lectures/TWP25/toctree.rst.txt b/293/_sources/lectures/TWP25/toctree.rst.txt new file mode 100644 index 0000000000..c302c0de7e --- /dev/null +++ b/293/_sources/lectures/TWP25/toctree.rst.txt @@ -0,0 +1,22 @@ +================ +Clases y objetos +================ + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP25_1.rst + TWP25_2.rst + TWP25_3.rst + TWP25_4.rst + TWP25_5.rst diff --git a/293/_sources/lectures/TWP25/toctree_en.rst.txt b/293/_sources/lectures/TWP25/toctree_en.rst.txt new file mode 100644 index 0000000000..9f945b6c8e --- /dev/null +++ b/293/_sources/lectures/TWP25/toctree_en.rst.txt @@ -0,0 +1,22 @@ +=================== +Classes and objects +=================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP25_1_en.rst + TWP25_2_en.rst + TWP25_3_en.rst + TWP25_4_en.rst + TWP25_5_en.rst diff --git a/293/_sources/lectures/TWP30/TWP30_1.rst.txt b/293/_sources/lectures/TWP30/TWP30_1.rst.txt new file mode 100644 index 0000000000..b8542f6267 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_1.rst.txt @@ -0,0 +1,57 @@ +Lo que aprendimos +================= + +Terminamos el primer libro +-------------------------- + +.. image:: ../img/TWP30_001.jpeg + :height: 14.384cm + :width: 10cm + :align: center + :alt: + + +Empecemos el segundo +-------------------- + +.. image:: ../img/TWP30_002.jpeg + :height: 13.801cm + :width: 13.801cm + :align: center + :alt: + + +Lo que hemos aprendimos +----------------------- + ++ Variables y entrada de datos ++ Condiciones ++ Repeticiones ++ Listas ++ Strings ++ Funciones ++ Archivos ++ Diccionarios ++ Clases y objetos + + +¿Qué aprenderemos en el segundo? +-------------------------------- + ++ ¡Las mismas cosas! ++ Hacer juegos ++ Acceso a sitios web para ver el precio del café ++ Uso de interfaces gráficas ++ Manejo de excepciones ++ Uso de la base de datos de surfistas ++ Mezcla de canciones + + +Encontrando tu camino +--------------------- + ++ Si solo usa el software de otros, siempre estará limitado a lo que + lo que otras personas piensan que quieres hacer ++ Escribe tus propios programas ++ ¿Quieres ser programado o ser el programador? ++ Puedes tomar el control diff --git a/293/_sources/lectures/TWP30/TWP30_1_en.rst.txt b/293/_sources/lectures/TWP30/TWP30_1_en.rst.txt new file mode 100644 index 0000000000..fe48f396fa --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_1_en.rst.txt @@ -0,0 +1,57 @@ +What we learned +=============== + +Finished the first book +----------------------- + +.. image:: ../img/TWP30_001.jpeg + :height: 14.384cm + :width: 10cm + :align: center + :alt: + + +Let's start the second one +--------------------------- + +.. image:: ../img/TWP30_002.jpeg + :height: 13.801cm + :width: 13.801cm + :align: center + :alt: + + +What we have learned +--------------------- + ++ Variables and data input ++ Conditions ++ Loops ++ Lists ++ Strings ++ Functions ++ Files ++ Dictionaries ++ Classes and objects + + +What will we learn in the second book? +--------------------------------------- + ++ The same things! ++ Making games ++ Accessing websites to see coffee prices ++ Using graphical interfaces ++ Exception handling ++ Using the surfer database ++ Mixing songs + + +Finding your way +----------------- + ++ If you only use other people's software, you'll always be limited to what + other people think you want to do ++ Write your own programs ++ Do you want to be programmed, or do you want to be the programmer? ++ You can take control \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/TWP30_2.rst.txt b/293/_sources/lectures/TWP30/TWP30_2.rst.txt new file mode 100644 index 0000000000..fe4308165a --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_2.rst.txt @@ -0,0 +1,88 @@ +.. role:: black +.. role:: blue +.. role:: red +.. role:: green +.. role:: purple +.. role:: yellow + +Las partes de tu programa +========================= + +Adivinando números +------------------ + +.. activecode:: ac_l30_2 + :nocodelens: + :stdin: + + print("Bienvenido!") + g = input("Ingrese un número: ") + numero = int(g) + if numero == 42: + print("¡Ganaste!") + else: + print("¡Tú perdiste!") + print("¡Fin del juego!") + + +Las partes del programa +----------------------- + +Ahora analizemos las partes del código anterior + +.. raw:: html + +
+ +
+ + print("Bienvenido!")
+ g = input("Ingrese un número: ")
+ numero = int(g)
+ if numero == 42:
+     print("¡Ganaste!")
+ else:
+     print("¡Tú perdiste!")
+ print("¡Fin del juego!")
+
+
+
+ +Tenga en cuenta que en el siguiente programa: + ++ Las partes en azul son :blue:`funciones` (ej: **print()**) ++ Las partes en rojo son :red:`strings o cadenas` (ej: **"¡Bienvenido!"**) ++ Las partes en verde son :green:`números` (ej: **42**) ++ Las partes en púrpura son :purple:`directivas` (ej: **if** y **else**) ++ Las partes en amarillo son :yellow:`indentaciones o sangría` ("Cada uno en su bloque") ++ Las partes en negro son :black:`variables` (ej: **g** y **numero**) ++ El símbolo de igual (``=``) es el operador de asignación y se usa para asignar valores a variables (ej: ``numero = int(g)`` La variable 'número' recibe un entero de g)) ++ El símbolo de doble igual (``==``) es el operador de comparación y se usa para comparar dos variables o valores (ej: ``numero == 42`` ¿el número es igual a 42?) ++ El símbolo de dos puntos (``:``) es el operador que abre un bloque de indentación. Va después de las directivas (ej: ``if numero == 42:`` y ``else:``) + +**Nota:** Estos son los colores de los bloques de código que haz visto durante el curso, pero estos colores pueden variar dependiendo de la herramienta que se use para programar. + +.. parsonsprob:: ac_l30_2a + :adaptive: + :numbered: left + + Construya el código anterior usando este ejercicio de arrastrar y soltar.(Use la función de ayuda si está atascado) + ----- + print("Bienvenido!") + g = input("Ingrese un número: ") + numero = int(g) + if numero == 42: + print("¡Ganaste!") + else: + print("¡Tú perdiste!") + print("¡Fin del juego!") \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/TWP30_2_en.rst.txt b/293/_sources/lectures/TWP30/TWP30_2_en.rst.txt new file mode 100644 index 0000000000..e0ee0f2b98 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_2_en.rst.txt @@ -0,0 +1,88 @@ +.. role:: black +.. role:: blue +.. role:: red +.. role:: green +.. role:: purple +.. role:: yellow + +The parts of your program +========================= + +Guessing numbers +---------------- + +.. activecode:: ac_l30_2_en + :nocodelens: + :stdin: + + print("Welcome!") + g = input("Enter a number: ") + number = int(g) + if number == 42: + print("You won!") + else: + print("You lost!") + print("End of the game!") + + +The parts of the program +------------------------ + +Now let's analyze the parts of the previous code + +.. raw:: html + +
+ +
+ + print("Welcome!")
+ g = input("Enter a number: ")
+ number = int(g)
+ if number == 42:
+     print("You won!")
+ else:
+     print("You lost!")
+ print("End of the game!")
+
+
+
+ +Note that in the following program: + ++ The parts in blue are :blue:`functions` (ex: **print()**) ++ The parts in red are :red:`strings` (ex: **"Welcome!"**) ++ The parts in green are :green:`numbers` (ex: **42**) ++ The parts in purple are :purple:`directives` (ex: **if** and **else**) ++ The parts in yellow are :yellow:`indentations` ("Each in their own block") ++ The parts in black are :black:`variables` (ex: **g** and **number**) ++ The equal sign (``=``) is the assignment operator and is used to assign values to variables (ex: ``number = int(g)`` The variable 'number' receives an integer from g)) ++ The double equal sign (``==``) is the comparison operator and is used to compare two variables or values (ex: ``number == 42`` Is the number equal to 42?) ++ The colon (``:``) is the operator that opens an indentation block. It goes after the directives (ex: ``if number == 42:`` and ``else:``) + +**Note:** These are the colors of the code blocks that you have seen during the course, but these colors may vary depending on the programming tool used. + +.. parsonsprob:: ac_l30_2a_en + :adaptive: + :numbered: left + + Build the previous code using this drag and drop exercise. (Use the hint function if you get stuck) + ----- + print("Welcome!") + g = input("Enter a number: ") + number = int(g) + if number == 42: + print("You won!") + else: + print("You lost!") + print("End of the game!") \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/TWP30_3.rst.txt b/293/_sources/lectures/TWP30/TWP30_3.rst.txt new file mode 100644 index 0000000000..f1074f2e01 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_3.rst.txt @@ -0,0 +1,44 @@ +¿Qué tipos de errores? +====================== + ++ Errores de sintaxis: un lenguaje de programación es formal, diferente de los lenguajes naturales, tiene una sintaxis rígida ++ Errores de tiempo de ejecución ++ Errores semánticos (más difíciles de encontrar) + + +¿Cómo encontrar y manejar errores? +---------------------------------- + ++ Sintáctica: mucha atención y práctica ++ En tiempo de ejecución: manejo de excepciones ++ Semántica: prueba de escritorio o simulación + + +Entonces, ¿cómo ejecutas tu código? +----------------------------------- + ++ Hay dos cosas para ejecutar el programa de adivinación: un editor y un intérprete ++ El editor guarda el código escrito en un archivo en el disco + +.. image:: ../img/TWP30_004.png + :height: 4.867cm + :width: 10.979cm + :align: center + :alt: + ++ Las computadoras no pueden procesar texto porque solo entienden binario (ceros y unos) ++ El intérprete convierte el código fuente en un archivo binario para la computadora + +.. image:: ../img/TWP30_005.png + :height: 5.921cm + :width: 13.2cm + :align: center + :alt: + + ++ El intérprete de Python funciona en dos modos: interactivo y de edición. ++ El modo interactivo es ideal para probar comandos y obtener respuestas instantáneas ++ Sin embargo, el modo de edición es el más utilizado para desarrollar los programas. + + Los nombres de archivo generalmente terminan con ".py" + + Si usa otra extensión, perderá colores ... ++ Un programa es más que una lista de comandos diff --git a/293/_sources/lectures/TWP30/TWP30_3_en.rst.txt b/293/_sources/lectures/TWP30/TWP30_3_en.rst.txt new file mode 100644 index 0000000000..459c7b14ec --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_3_en.rst.txt @@ -0,0 +1,44 @@ +What types of errors? +====================== + ++ Syntax errors: a programming language is formal, different from natural languages, and has a rigid syntax. ++ Runtime errors ++ Semantic errors (more difficult to find) + + +How to find and handle errors? +------------------------------- + ++ Syntax: pay close attention and practice ++ During runtime: exception handling ++ Semantic: desk testing or simulation + + +So, how do you run your code? +------------------------------ + ++ There are two things to run the guessing game program: an editor and an interpreter ++ The editor saves the code written in a file on the disk + +.. image:: ../img/TWP30_004.png + :height: 4.867cm + :width: 10.979cm + :align: center + :alt: + ++ Computers cannot process text because they only understand binary (zeros and ones) ++ The interpreter converts the source code into a binary file for the computer + +.. image:: ../img/TWP30_005.png + :height: 5.921cm + :width: 13.2cm + :align: center + :alt: + + ++ The Python interpreter works in two modes: interactive and editing. ++ The interactive mode is ideal for testing commands and getting instant responses ++ However, the editing mode is the most commonly used for developing programs. + + File names usually end with ".py" + + If you use another extension, you'll lose colors... ++ A program is more than a list of commands. \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/TWP30_4.rst.txt b/293/_sources/lectures/TWP30/TWP30_4.rst.txt new file mode 100644 index 0000000000..5befe06ab5 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_4.rst.txt @@ -0,0 +1,68 @@ +El programa es una red de carreteras +==================================== + +.. codelens:: cl_l30_4 + + print("¡Bienvenido a mi programa!") + print("¡Vuelva siempre!") + +.. image:: ../img/TWP10_002.jpg + :height: 5.524cm + :width: 22.859cm + :align: center + :alt: + +.. image:: ../img/TWP10_004.png + :height: 12.571cm + :width: 18.78cm + :align: center + :alt: + + +En la red eliges tu camino +-------------------------- + +.. image:: ../img/TWP10_009.jpg + :height: 9.754cm + :width: 22.859cm + :align: center + :alt: + + +Consejos +-------- + ++ El programa de adivinar números solo dice si lo hiciste bien o no ++ Para ayudarlo a decir "Alto" o "Bajo" si la persona está equivocada ¿Cómo se vería el camino? + +.. image:: ../img/TWP30_006.jpg + :height: 5.814cm + :width: 10.8cm + :align: center + :alt: + +.. activecode:: ac_l30_4 + :nocodelens: + :stdin: + + print("Bienvenido") + g = input("Ingrese un número:") + numero = int(g) + if numero == 42: + print("¡Ganaste!") + else: + if numero > 42: + print("Alto") + else: + print("Bajo") + print("Fin del juego") + + +A los usuarios todavía no les gusta +----------------------------------- + +.. image:: ../img/TWP30_009.jpg + :height: 12.571cm + :width: 7.946cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP30/TWP30_4_en.rst.txt b/293/_sources/lectures/TWP30/TWP30_4_en.rst.txt new file mode 100644 index 0000000000..b850670d13 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_4_en.rst.txt @@ -0,0 +1,68 @@ +The program is a network of roads +================================= + +.. codelens:: cl_l30_4_en + + print("Welcome to my program!") + print("Come back anytime!") + +.. image:: ../img/TWP10_002.jpg + :height: 5.524cm + :width: 22.859cm + :align: center + :alt: + +.. image:: ../img/TWP10_004.png + :height: 12.571cm + :width: 18.78cm + :align: center + :alt: + + +In the network, you choose your path +------------------------------------- + +.. image:: ../img/TWP10_009.jpg + :height: 9.754cm + :width: 22.859cm + :align: center + :alt: + + +Tips +---- + ++ The guessing game program only tells you if you guessed correctly or not. ++ To help it say "High" or "Low" if the person is wrong, how would the path look? + +.. image:: ../img/TWP30_006.jpg + :height: 5.814cm + :width: 10.8cm + :align: center + :alt: + +.. activecode:: ac_l30_4_en + :nocodelens: + :stdin: + + print("Welcome") + g = input("Enter a number:") + number = int(g) + if number == 42: + print("You won!") + else: + if number > 42: + print("High") + else: + print("Low") + print("End of game") + + +Users still don't like it +------------------------- + +.. image:: ../img/TWP30_009.jpg + :height: 12.571cm + :width: 7.946cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/TWP30_5.rst.txt b/293/_sources/lectures/TWP30/TWP30_5.rst.txt new file mode 100644 index 0000000000..ede30af30b --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_5.rst.txt @@ -0,0 +1,69 @@ +Repeticiones +============ + +.. image:: ../img/TWP15_001.jpg + :height: 15.602cm + :width: 16.801cm + :align: center + :alt: + + +.. activecode:: ac_l30_5 + :language: python3 + :python3_interpreter: brython + + from browser import document as doc + from browser import html + from browser import timer + + print("¡Bienvenido!") + numero = 0 + + doc <= html.DIV(id="div_juego") + + # Creamos el botón para jugar + doc["div_juego"] <= html.BUTTON("Jugar", id="btn_jugar") + + # Definimos lo que hará el boton cuando sea apretado + def adivinar(): + + global numero + numero = int(input("Adivine el número: ")) + if numero == 42: + print("¡Ganaste!") + else: + if numero > 42: + print("Alto") + else: + print("Bajo") + + if numero != 42: + # Si el número no se adivinó, se repite la función después de + # 3 segundos + timer.set_timeout(adivinar, 3000) + + + def empezar(ev): + adivinar() + + # Cuando el botón sea apretado, llamará a la función empezar, + # que a su vez llamará a adivinar. + doc["btn_jugar"].bind("click", empezar) + + +.. image:: ../img/TWP15_007.png + :height: 14.804cm + :width: 22.181cm + :align: center + :alt: + + +A los usuarios todavía no les gusta +----------------------------------- + + +.. image:: ../img/TWP30_0092.jpg + :height: 12.571cm + :width: 7.946cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP30/TWP30_5_en.rst.txt b/293/_sources/lectures/TWP30/TWP30_5_en.rst.txt new file mode 100644 index 0000000000..09d52a1387 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_5_en.rst.txt @@ -0,0 +1,67 @@ +Repetitions +============ + +.. image:: ../img/TWP15_001.jpg + :height: 15.602cm + :width: 16.801cm + :align: center + :alt: + +.. activecode:: ac_l30_5_en + :language: python3 + :python3_interpreter: brython + + from browser import document as doc + from browser import html + from browser import timer + + print("Welcome!") + number = 0 + + doc <= html.DIV(id="div_game") + + # Create the button to play + doc["div_game"] <= html.BUTTON("Play", id="btn_play") + + # Define what the button will do when pressed + def guess(): + + global number + number = int(input("Guess the number: ")) + if number == 42: + print("You won!") + else: + if number > 42: + print("High") + else: + print("Low") + + if number != 42: + # If the number was not guessed, repeat the function after + # 3 seconds + timer.set_timeout(guess, 3000) + + + def start(ev): + guess() + + # When the button is pressed, it will call the start function, + # which in turn will call guess + doc["btn_play"].bind("click", start) + + +.. image:: ../img/TWP15_007.png + :height: 14.804cm + :width: 22.181cm + :align: center + :alt: + + +Users Still Dislike It +----------------------- + +.. image:: ../img/TWP30_0092.jpg + :height: 12.571cm + :width: 7.946cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/TWP30_6.rst.txt b/293/_sources/lectures/TWP30/TWP30_6.rst.txt new file mode 100644 index 0000000000..610a68ab29 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_6.rst.txt @@ -0,0 +1,62 @@ +Sortear el número a adivinar +============================ + + +.. activecode:: ac_l30_6 + :language: python3 + :python3_interpreter: brython + + from browser import document as doc + from browser import html + from browser import timer + from random import randint + + print("¡Bienvenido!") + azar = randint(1, 100) + numero = 0 + + doc <= html.DIV(id="div_juego_2") + + # Creamos una caja de texto donde ingresar el número que queramos + doc["div_juego_2"] <= html.INPUT(id="inp_adivinar", placeholder="Adivine el número", type="number") + # Creamos el botón para adivinar + doc["div_juego_2"] <= html.BUTTON("Enviar adivinanza", id="btn_adivinar") + html.BR() + + def confirmar_adivinanza(e): + global numero + numero = int(doc["inp_adivinar"].value) + + if numero == azar: + print("¡Ganaste!") + print("¡Fin del juego!") + # Si el número es adivinado, el botón desaparece y el juego + # termina + doc["btn_adivinar"].style.display = "none" + else: + if numero > azar: + print("Alto") + else: + print("Bajo") + + # Al apretar el botón, invoca a la función confirmar_adivinanza + doc["btn_adivinar"].bind("click", confirmar_adivinanza) + + +¡Ahora sí! +---------- + +.. image:: ../img/TWP30_012.jpg + :height: 10.873cm + :width: 14.154cm + :alt: + + +Resumen +------- + ++ ¡Creaste un juego! ++ Los comandos hacen cosas ++ Las condicionales deciden las cosas ++ Los ciclos repiten cosas ++ Las condiciones te ayudan a decidir si algo es verdadero o falso ++ La asignación define un nombre para un valor. diff --git a/293/_sources/lectures/TWP30/TWP30_6_en.rst.txt b/293/_sources/lectures/TWP30/TWP30_6_en.rst.txt new file mode 100644 index 0000000000..0474df6f0f --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_6_en.rst.txt @@ -0,0 +1,61 @@ +Raffle the number to guess +============================ + + +.. activecode:: ac_l30_6_en + :language: python3 + :python3_interpreter: brython + + from browser import document as doc + from browser import html + from browser import timer + from random import randint + + print("Welcome!") + random_number = randint(1, 100) + number = 0 + + doc <= html.DIV(id="div_game_2") + + # We create a text box where to enter the number we want + doc["div_game_2"] <= html.INPUT(id="inp_guess", placeholder="Guess the number", type="number") + # We create the button to guess + doc["div_game_2"] <= html.BUTTON("Submit guess", id="btn_guess") + html.BR() + + def confirm_guess(e): + global number + number = int(doc["inp_guess"].value) + + if number == random_number: + print("You won!") + print("End of game!") + # If the number is guessed, the button disappears and the game ends + doc["btn_guess"].style.display = "none" + else: + if number > random_number: + print("High") + else: + print("Low") + + # When you press the button, it invokes the confirm_guess function + doc["btn_guess"].bind("click", confirm_guess) + + +Now it's on! +------------ + +.. image:: ../img/TWP30_012.jpg + :height: 10.873cm + :width: 14.154cm + :alt: + + +Summary +------- + ++ You created a game! ++ Commands do things ++ Conditionals decide things ++ Loops repeat things ++ Conditions help you decide if something is true or false ++ Assignment defines a name for a value. \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/TWP30_7.rst.txt b/293/_sources/lectures/TWP30/TWP30_7.rst.txt new file mode 100644 index 0000000000..1b20186d96 --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_7.rst.txt @@ -0,0 +1,31 @@ +Herramientas de Python +====================== + ++ Condiciones: ``if``, ``elif``, ``else`` ++ Ciclo: ``while`` ++ Operador de asignación: ``=`` ++ Operador de igualdad: ``==`` ++ Operador diferente de: ``!=`` ++ Mostrar un mensaje: ``print()`` ++ Leer una entrada del usuario: ``input()`` ++ Convertir a entero: ``int()`` ++ Sortear un entero: ``randint()`` + +Estas son algunas de las herramientas. ¡Existen muchas más! + +Ahora solo faltan tus ejercicios +-------------------------------- + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + + +.. raw:: html + +
+ + +“La vida es como andar en bicicleta. Para mantener el equilibrio, debes seguir moviéndote ”. - Einstein diff --git a/293/_sources/lectures/TWP30/TWP30_7_en.rst.txt b/293/_sources/lectures/TWP30/TWP30_7_en.rst.txt new file mode 100644 index 0000000000..19d3ff09ed --- /dev/null +++ b/293/_sources/lectures/TWP30/TWP30_7_en.rst.txt @@ -0,0 +1,31 @@ +Python Tools +====================== + ++ Conditions: ``if``, ``elif``, ``else`` ++ Loop: ``while`` ++ Assignment operator: ``=`` ++ Equality operator: ``==`` ++ Inequality operator: ``!=`` ++ Display a message: ``print()`` ++ Read user input: ``input()`` ++ Convert to integer: ``int()`` ++ Generate a random integer: ``randint()`` + +These are some of the tools. There are many more! + +Now all that's left are your exercises +-------------------------------------- + +.. image:: ../img/TWP05_041.jpeg + :height: 12.571cm + :width: 9.411cm + :align: center + :alt: + + +.. raw:: html + +
+ + +"Life is like riding a bicycle. To keep your balance, you must keep moving." - Einstein \ No newline at end of file diff --git a/293/_sources/lectures/TWP30/toctree.rst.txt b/293/_sources/lectures/TWP30/toctree.rst.txt new file mode 100644 index 0000000000..3ed6506250 --- /dev/null +++ b/293/_sources/lectures/TWP30/toctree.rst.txt @@ -0,0 +1,24 @@ +================== +Revisión general 1 +================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP30_1.rst + TWP30_2.rst + TWP30_3.rst + TWP30_4.rst + TWP30_5.rst + TWP30_6.rst + TWP30_7.rst diff --git a/293/_sources/lectures/TWP30/toctree_en.rst.txt b/293/_sources/lectures/TWP30/toctree_en.rst.txt new file mode 100644 index 0000000000..c1a026ce1c --- /dev/null +++ b/293/_sources/lectures/TWP30/toctree_en.rst.txt @@ -0,0 +1,24 @@ +================= +General review 1 +================= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP30_1_en.rst + TWP30_2_en.rst + TWP30_3_en.rst + TWP30_4_en.rst + TWP30_5_en.rst + TWP30_6_en.rst + TWP30_7_en.rst diff --git a/293/_sources/lectures/TWP33/TWP33_1.rst.txt b/293/_sources/lectures/TWP33/TWP33_1.rst.txt new file mode 100644 index 0000000000..47f2f19eb1 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_1.rst.txt @@ -0,0 +1,56 @@ +Starbuzz Café +============= + +.. image:: ../img/TWP33_001.jpg + :height: 15.427cm + :width: 14.801cm + :align: center + :alt: + + +Código Starbuzz actual +---------------------- + +.. activecode:: ac_l33_1 + :nocodelens: + :stdin: + + from urllib.request import urlopen + + precios = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices.html" + pagina = urlopen(precios) + texto = pagina.read() + print(texto) + + +El CEO solo quiere el precio +---------------------------- + + +.. image:: ../img/TWP33_004.jpg + :height: 6.719cm + :width: 12.699cm + :align: center + :alt: + ++ Este es el texto HTML "en bruto", que es el formato de las páginas web. ++ El precio está incrustado en HTML + +.. code-block:: html + + Welcome to the Beans'R'Us Pricing Page + + +

Welcome to the Beans'R'Us Pricing Page

+

Current price of coffee beans = $6.73

+

Price valid for 15 minutes from Sun Jul 11 03:08:01 2021.

+ + + ++ Recibimos el output anterior como una string o cadena de caracteres. + +.. image:: ../img/TWP33_005.png + :height: 2.112cm + :width: 23.745cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_1_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_1_en.rst.txt new file mode 100644 index 0000000000..b906015222 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_1_en.rst.txt @@ -0,0 +1,55 @@ +Starbuzz Café +============= + +.. image:: ../img/TWP33_001.jpg + :height: 15.427cm + :width: 14.801cm + :align: center + :alt: + + +Current Starbuzz code +---------------------- + +.. activecode:: ac_l33_1_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + + prices = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices.html" + page = urlopen(prices) + text = page.read() + print(text) + + +The CEO only wants the price +----------------------------- + +.. image:: ../img/TWP33_004.jpg + :height: 6.719cm + :width: 12.699cm + :align: center + :alt: + ++ This is the "raw" HTML text, which is the format of web pages. ++ The price is embedded in HTML. + +.. code-block:: html + + Welcome to the Beans'R'Us Pricing Page + + +

Welcome to the Beans'R'Us Pricing Page

+

Current price of coffee beans = $6.73

+

Price valid for 15 minutes from Sun Jul 11 03:08:01 2021.

+ + + ++ We receive the above output as a string of characters. + +.. image:: ../img/TWP33_005.png + :height: 2.112cm + :width: 23.745cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_2.rst.txt b/293/_sources/lectures/TWP33/TWP33_2.rst.txt new file mode 100644 index 0000000000..903217cd19 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_2.rst.txt @@ -0,0 +1,28 @@ +¿Cómo obtener solo el precio? +============================= + +.. image:: ../img/TWP33_006.png + :height: 3.436cm + :width: 22.621cm + :align: center + :alt: + + +.. image:: ../img/TWP33_007.jpg + :height: 5cm + :width: 16.051cm + :align: center + :alt: + + +.. image:: ../img/TWP33_008.jpg + :height: 8.323cm + :width: 16.483cm + :align: center + :alt: + +.. image:: ../img/TWP33_009.jpg + :height: 7.317cm + :width: 17.805cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP33/TWP33_2_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_2_en.rst.txt new file mode 100644 index 0000000000..010f30c5a0 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_2_en.rst.txt @@ -0,0 +1,30 @@ +How to get only the price? +=========================== + +.. image:: ../img/TWP33_006.png + :height: 3.436cm + :width: 22.621cm + :align: center + :alt: + + +.. image:: ../img/TWP33_007.jpg + :height: 5cm + :width: 16.051cm + :align: center + :alt: + + +.. image:: ../img/TWP33_008.jpg + :height: 8.323cm + :width: 16.483cm + :align: center + :alt: + +.. image:: ../img/TWP33_009.jpg + :height: 7.317cm + :width: 17.805cm + :align: center + :alt: + + diff --git a/293/_sources/lectures/TWP33/TWP33_3.rst.txt b/293/_sources/lectures/TWP33/TWP33_3.rst.txt new file mode 100644 index 0000000000..8ed040b0a3 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_3.rst.txt @@ -0,0 +1,58 @@ +Cortar +====== + +.. codelens:: cl_l33_3 + + texto = "Palmeras" + print(texto[2:5]) + print(texto[0:3]) + print(texto[4:6]) + ++ Corta el primer número antes del segundo. ++ ¡No incluye el segundo número! + +.. image:: ../img/TWP33_012.jpg + :height: 10.323cm + :width: 19.483cm + :align: center + :alt: + +.. activecode:: ac_l33_3a + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_PRECIOS = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices.html" + pagina = urlopen(URL_PRECIOS) + texto = pagina.read() + print(texto[234:238]) + + +¡El CEO está feliz! +------------------- + +.. image:: ../img/TWP33_015.jpg + :height: 7.402cm + :width: 14.922cm + :align: center + :alt: + + +No hay preguntas tontas +----------------------- + ++ ¿Puedo poner alguna página web en este código? ++ Sí. Siéntete libre, pero no olvides la decodificación ++ Por ejemplo, el siguiente `sitio web `_ muestra caracteres con la decodificación iso8859. ++ ¿Qué hace ``urllib.request``? ++ Te permite chatear con internet. ++ ¿Puedo acceder a una página directamente en el navegador? ++ Sí ejecute el código de abajo que utiliza ``import antigravity``. + +.. activecode:: ac_l33_3b + :language: python3 + :python3_interpreter: brython + + import antigravity + # Ejecuta este codigo diff --git a/293/_sources/lectures/TWP33/TWP33_3_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_3_en.rst.txt new file mode 100644 index 0000000000..17244ec4c3 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_3_en.rst.txt @@ -0,0 +1,58 @@ +Cut +=== + +.. codelens:: cl_l33_3_en + + text = "Palms" + print(text[2:5]) + print(text[0:3]) + print(text[4:6]) + ++ Cuts before the second number. ++ Does not include the second number! + +.. image:: ../img/TWP33_012.jpg + :height: 10.323cm + :width: 19.483cm + :align: center + :alt: + +.. activecode:: ac_l33_3a_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + + PRICES_URL = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices.html" + page = urlopen(PRICES_URL) + text = page.read() + print(text[234:238]) + + +The CEO is happy! +------------------ + +.. image:: ../img/TWP33_015.jpg + :height: 7.402cm + :width: 14.922cm + :align: center + :alt: + + +There are no stupid questions +----------------------------- + ++ Can I put any website in this code? ++ Yes. Feel free, but don't forget about decoding. ++ For example, the following `website `_ displays characters with iso8859 decoding. ++ What does ``urllib.request`` do? ++ It allows you to chat with the internet. ++ Can I access a page directly in the browser? ++ Yes, run the code below which uses ``import antigravity``. + +.. activecode:: ac_l33_3b_en + :language: python3 + :python3_interpreter: brython + + import antigravity + # Run this code \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_4.rst.txt b/293/_sources/lectures/TWP33/TWP33_4.rst.txt new file mode 100644 index 0000000000..d477579a26 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_4.rst.txt @@ -0,0 +1,37 @@ +Descuentos para clientes leales +=============================== + +.. image:: ../img/TWP33_016.jpg + :height: 12.571cm + :width: 17.458cm + :align: center + :alt: + + +Programa de fidelización +------------------------ + +.. activecode:: ac_l33_4 + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_PRECIOS_LOYALTY = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + pagina = urlopen(URL_PRECIOS_LOYALTY) + texto = pagina.read() + print(texto[234:238]) + ++ ¡No funcionó! la cadena "Bean" apareció en lugar del precio. ¿Por qué sera? + + +El precio se movió +------------------ + ++ Las páginas son diferentes y el precio cambia de posición en la cadena + +.. image:: ../img/TWP33_018.jpg + :height: 8.416cm + :width: 16.122cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP33/TWP33_4_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_4_en.rst.txt new file mode 100644 index 0000000000..56dca3b63c --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_4_en.rst.txt @@ -0,0 +1,37 @@ +Discounts for loyal customers +============================== + +.. image:: ../img/TWP33_016.jpg + :height: 12.571cm + :width: 17.458cm + :align: center + :alt: + + +Loyalty program +------------------------ + +.. activecode:: ac_l33_4_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + + LOYALTY_PRICES_URL = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + page = urlopen(LOYALTY_PRICES_URL) + text = page.read() + print(text[234:238]) + ++ It didn't work! the string "Bean" appeared instead of the price. Why could it be? + + +The price moved +------------------ + ++ The pages are different and the price changes position in the string + +.. image:: ../img/TWP33_018.jpg + :height: 8.416cm + :width: 16.122cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_5.rst.txt b/293/_sources/lectures/TWP33/TWP33_5.rst.txt new file mode 100644 index 0000000000..b134f4ab9a --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_5.rst.txt @@ -0,0 +1,38 @@ +Los datos de Python son inteligentes +==================================== + ++ Los lenguajes de programación proporcionan funcionalidades incorporadas en los datos para ayudarte. ++ Los datos de Python son inteligentes: pueden hacer cosas. + +.. codelens:: cl_l33_5a + + texto = "anita lava la tina" + print(texto.upper()) + print(texto.split()) + + +Método ``find`` +--------------- + ++ Método ``find`` para strings + +.. codelens:: cl_l33_5b + + texto = "Palmeras" + print(texto.find("P")) + print(texto.find("lmer")) + print(texto.find("Pa")) + +.. activecode:: ac_l33_5 + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_PRECIOS_LOYALTY = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + pagina = urlopen(URL_PRECIOS_LOYALTY) + texto = pagina.read() + ubicacion = texto.find(">$") + inicio = ubicacion + 2 + fin = inicio + 4 + print(texto[inicio:fin]) diff --git a/293/_sources/lectures/TWP33/TWP33_5_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_5_en.rst.txt new file mode 100644 index 0000000000..178547f5ce --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_5_en.rst.txt @@ -0,0 +1,37 @@ +Python data is intelligent +=========================== + ++ Programming languages provide built-in functionalities in data to assist you. ++ Python data is intelligent: it can do things. + +.. codelens:: cl_l33_5a_en + + text = "anita lava la tina" + print(text.upper()) + print(text.split()) + +``find`` method +--------------- + ++ ``find`` method for strings + +.. codelens:: cl_l33_5b_en + + text = "Palmeras" + print(text.find("P")) + print(text.find("lmer")) + print(text.find("Pa")) + +.. activecode:: ac_l33_5_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_LOYALTY_PRICES = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + page = urlopen(URL_LOYALTY_PRICES) + text = page.read() + location = text.find(">$") + start = location + 2 + end = start + 4 + print(text[start:end]) \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_6.rst.txt b/293/_sources/lectures/TWP33/TWP33_6.rst.txt new file mode 100644 index 0000000000..f3a3dc556f --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_6.rst.txt @@ -0,0 +1,23 @@ +Solo cuando es inferior a 4,74 +============================== + +.. image:: ../img/TWP33_025.jpg + :height: 15.444cm + :width: 8.6cm + :align: center + :alt: + +.. activecode:: ac_l33_6 + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_PRECIOS_LOYALTY = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + pagina = urlopen(URL_PRECIOS_LOYALTY) + texto = pagina.read() + ubicacion = texto.find(">$") + inicio = ubicacion + 2 + fin = inicio + 4 + if texto[inicio:fin] < 4.74: + print(texto[inicio:fin]) diff --git a/293/_sources/lectures/TWP33/TWP33_6_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_6_en.rst.txt new file mode 100644 index 0000000000..e6af319b34 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_6_en.rst.txt @@ -0,0 +1,23 @@ +Only when it is less than 4.74 +================================= + +.. image:: ../img/TWP33_025.jpg + :height: 15.444cm + :width: 8.6cm + :align: center + :alt: + +.. activecode:: ac_l33_6_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + + LOYALTY_PRICES_URL = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + page = urlopen(LOYALTY_PRICES_URL) + content = page.read() + position = content.find(">$") + start = position + 2 + end = start + 4 + if content[start:end] < 4.74: + print(content[start:end]) \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_7.rst.txt b/293/_sources/lectures/TWP33/TWP33_7.rst.txt new file mode 100644 index 0000000000..69513211b4 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_7.rst.txt @@ -0,0 +1,66 @@ +Los strings son diferentes de los números +========================================= + +.. image:: ../img/TWP33_028.jpg + :height: 9.324cm + :width: 17.401cm + :align: center + :alt: + + +Convertir a ``float`` +--------------------- + +.. activecode:: ac_l33_7a + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_PRECIOS_LOYALTY = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + pagina = urlopen(URL_PRECIOS_LOYALTY) + texto = pagina.read() + ubicacion = texto.find(">$") + inicio = ubicacion + 2 + fin = inicio + 4 + if float(texto[inicio:fin]) < 4.74: + print("Comprar! precio: %5.2f" % float(texto[inicio:fin])) + +¿Puede seguir probando el precio? +--------------------------------- + +.. image:: ../img/TWP33_029.jpg + :height: 15.444cm + :width: 8.6cm + :align: center + :alt: + +¿Puede seguir intentándolo? +--------------------------- + +.. activecode:: ac_l33_7b + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_PRECIOS_LOYALTY = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + precio = 99.99 + while precio >= 4.74: + pagina = urlopen(URL_PRECIOS_LOYALTY) + texto = pagina.read() + ubicacion = texto.find(">$") + inicio = ubicacion + 2 + fin = inicio + 4 + precio = float(texto[inicio:fin]) + print("Comprar! precio: %5.2f" % precio) + + +¡El CEO está muy feliz! +----------------------- + +.. image:: ../img/TWP33_030.jpg + :height: 9.762cm + :width: 11.561cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP33/TWP33_7_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_7_en.rst.txt new file mode 100644 index 0000000000..bf6f452871 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_7_en.rst.txt @@ -0,0 +1,66 @@ +Strings are different from numbers +=================================== + +.. image:: ../img/TWP33_028.jpg + :height: 9.324cm + :width: 17.401cm + :align: center + :alt: + + +Convert to ``float`` +-------------------- + +.. activecode:: ac_l33_7a_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_LOYALTY_PRICES = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + page = urlopen(URL_LOYALTY_PRICES) + text = page.read() + location = text.find(">$") + start = location + 2 + end = start + 4 + if float(text[start:end]) < 4.74: + print("Buy! price: %5.2f" % float(text[start:end])) + +Can you keep testing the price? +------------------------------- + +.. image:: ../img/TWP33_029.jpg + :height: 15.444cm + :width: 8.6cm + :align: center + :alt: + +Can you keep trying? +-------------------- + +.. activecode:: ac_l33_7b_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + + URL_LOYALTY_PRICES = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + price = 99.99 + while price >= 4.74: + page = urlopen(URL_LOYALTY_PRICES) + text = page.read() + location = text.find(">$") + start = location + 2 + end = start + 4 + price = float(text[start:end]) + print("Buy! price: %5.2f" % price) + + +The CEO is very happy! +----------------------- + +.. image:: ../img/TWP33_030.jpg + :height: 9.762cm + :width: 11.561cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_8.rst.txt b/293/_sources/lectures/TWP33/TWP33_8.rst.txt new file mode 100644 index 0000000000..8db5ea0c7f --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_8.rst.txt @@ -0,0 +1,30 @@ +Algo salió mal +============== + +.. image:: ../img/TWP33_032.jpg + :height: 15.268cm + :width: 15.201cm + :align: center + :alt: + +Acusación DDoS +-------------- + ++ DDoS – Distributed Denial of Service ++ Ataque de denegación de servicio. + +.. image:: ../img/TWP33_033.jpg + :height: 13.596cm + :width: 15.201cm + :align: center + :alt: + + +Recibimos un mensaje +-------------------- + +.. image:: ../img/TWP33_034.jpg + :height: 13.191cm + :width: 22.685cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP33/TWP33_8_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_8_en.rst.txt new file mode 100644 index 0000000000..072772ea7c --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_8_en.rst.txt @@ -0,0 +1,29 @@ +Something went wrong +===================== + +.. image:: ../img/TWP33_032.jpg + :height: 15.268cm + :width: 15.201cm + :align: center + :alt: + +DDoS Accusation +--------------- + ++ DDoS - Distributed Denial of Service ++ Denial of Service attack. + +.. image:: ../img/TWP33_033.jpg + :height: 13.596cm + :width: 15.201cm + :align: center + :alt: + +We received a message +---------------------- + +.. image:: ../img/TWP33_034.jpg + :height: 13.191cm + :width: 22.685cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/TWP33_9.rst.txt b/293/_sources/lectures/TWP33/TWP33_9.rst.txt new file mode 100644 index 0000000000..7b28a21f36 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_9.rst.txt @@ -0,0 +1,68 @@ +Biblioteca ``time`` +=================== + ++ Tiempo actual en segundos ``time.clock()`` ++ ¿Estoy en verano? ``time.daylight()`` ++ Duerme unos segundos, ``time.sleep(segundos)`` ++ Zona horaria ``time.timezone()`` + + +10 segundos entre cada acceso +----------------------------- + +.. activecode:: ac_l33_9 + :nocodelens: + :stdin: + + from urllib.request import urlopen + import time + + # Esto nos sirve para aumentar la duración del programa a 3 minutos. + import sys + sys.setExecutionLimit(180000) + + URL_PRECIOS_LOYALTY = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + precio = 99.99 + limite = 0 + disponibilidad = True + while precio >= 4.74 or limite <=15: + try: + pagina = urlopen(URL_PRECIOS_LOYALTY) + except: + print("URL no disponilbe por este momento.") + disponibilidad = False + break + pagina = urlopen(URL_PRECIOS_LOYALTY) + texto = pagina.read() + ubicacion = texto.find(">$") + inicio = ubicacion + 2 + fin = inicio + 4 + precio = float(texto[inicio:fin]) + if precio >= 4.74: + print("Esperando 10 segundos... Precio actual: %5.2f" % precio) + limite += 1 + time.sleep(10) + if limite == 16: + print("No quieren bajar el precio. Comprar a %5.2f pesos" % precio) + elif limite < 7 and disponibilidad == True: + print("Comprar! precio: %5.2f" % precio) + + +Resumen +------- + ++ Los ``string`` son cadenas de caracteres. ++ Accedemos a los caracteres individuales por el índice, que comienza con cero. ++ Los métodos son funciones integradas en variables. ++ Hay bibliotecas de programación con código listo. ++ Los datos tienen un tipo, como ``int`` o ``string``. + + +Herramientas de Python +---------------------- + ++ ``texto[4]`` accede al quinto carácter. ++ ``texto[4:9]`` accede del quinto al noveno carácter. ++ El método ``text.find()`` busca una subcadena. ++ ``float()`` convierte algo a un punto flotante. ++ Bibliotecas: ``urllib.request`` y ``time``. diff --git a/293/_sources/lectures/TWP33/TWP33_9_en.rst.txt b/293/_sources/lectures/TWP33/TWP33_9_en.rst.txt new file mode 100644 index 0000000000..95df7617c5 --- /dev/null +++ b/293/_sources/lectures/TWP33/TWP33_9_en.rst.txt @@ -0,0 +1,68 @@ +Library ``time`` +================= + ++ Current time in seconds ``time.clock()`` ++ Am I in daylight saving time? ``time.daylight()`` ++ Sleep for a few seconds, ``time.sleep(seconds)`` ++ Timezone ``time.timezone()`` + + +10 seconds between each access +------------------------------ + +.. activecode:: ac_l33_9_en + :nocodelens: + :stdin: + + from urllib.request import urlopen + import time + + # This is used to increase the program duration to 3 minutes. + import sys + sys.setExecutionLimit(180000) + + LOYALTY_PRICES_URL = "https://api.allorigins.win/raw?url=http://beans.itcarlow.ie/prices-loyalty.html" + price = 99.99 + limit = 0 + availability = True + while price >= 4.74 or limit <=15: + try: + page = urlopen(LOYALTY_PRICES_URL) + except: + print("URL not available at this time.") + availability = False + break + page = urlopen(LOYALTY_PRICES_URL) + text = page.read() + location = text.find(">$") + start = location + 2 + end = start + 4 + price = float(text[start:end]) + if price >= 4.74: + print("Waiting 10 seconds... Current price: %5.2f" % price) + limit += 1 + time.sleep(10) + if limit == 16: + print("They don't want to lower the price. Buy it for %5.2f pesos" % price) + elif limit < 7 and availability == True: + print("Buy! price: %5.2f" % price) + + +Summary +------- + ++ Strings are character strings. ++ We access individual characters by their index, starting at zero. ++ Methods are functions built into variables. ++ There are programming libraries with ready-made code. ++ Data has a type, such as ``int`` or ``string``. + + +Python Tools +------------ + ++ ``text[4]`` accesses the fifth character. ++ ``text[4:9]`` accesses from the fifth to the ninth character. ++ The method ``text.find()`` searches for a substring. ++ ``float()`` converts something to a floating point number. ++ Libraries: ``urllib.request`` and ``time``. \ No newline at end of file diff --git a/293/_sources/lectures/TWP33/toctree.rst.txt b/293/_sources/lectures/TWP33/toctree.rst.txt new file mode 100644 index 0000000000..cfe4416377 --- /dev/null +++ b/293/_sources/lectures/TWP33/toctree.rst.txt @@ -0,0 +1,32 @@ +================== +Revisión de String +================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + ++ Es difícil comunicarse sin palabras. ++ Entre los diversos tipos de datos, uno de los más importantes son las cadenas o ``string``. ++ **Nota**: no es tan fácil manipular cadenas en algunos lenguajes de programación. ++ Busquemos dónde está la información en un texto. ++ Y aprenderemos uno de los conceptos más importantes de orientación a la objetos: métodos + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP33_1.rst + TWP33_2.rst + TWP33_3.rst + TWP33_4.rst + TWP33_5.rst + TWP33_6.rst + TWP33_7.rst + TWP33_8.rst + TWP33_9.rst diff --git a/293/_sources/lectures/TWP33/toctree_en.rst.txt b/293/_sources/lectures/TWP33/toctree_en.rst.txt new file mode 100644 index 0000000000..4b50603daa --- /dev/null +++ b/293/_sources/lectures/TWP33/toctree_en.rst.txt @@ -0,0 +1,32 @@ +============= +String Review +============= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + ++ Es difícil comunicarse sin palabras. ++ Entre los diversos tipos de datos, uno de los más importantes son las cadenas o ``string``. ++ **Nota**: no es tan fácil manipular cadenas en algunos lenguajes de programación. ++ Busquemos dónde está la información en un texto. ++ Y aprenderemos uno de los conceptos más importantes de orientación a la objetos: métodos + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP33_1_en.rst + TWP33_2_en.rst + TWP33_3_en.rst + TWP33_4_en.rst + TWP33_5_en.rst + TWP33_6_en.rst + TWP33_7_en.rst + TWP33_8_en.rst + TWP33_9_en.rst diff --git a/293/_sources/lectures/TWP35/TWP35_1.rst.txt b/293/_sources/lectures/TWP35/TWP35_1.rst.txt new file mode 100644 index 0000000000..9b80ea20cb --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_1.rst.txt @@ -0,0 +1,20 @@ +Seamos más organizados +====================== + + +.. image:: ../img/TWP35_001.jpeg + :height: 13.35cm + :width: 17.801cm + :align: center + :alt: + +.. image:: ../img/TWP35_002.jpeg + :height: 14.064cm + :width: 16.601cm + :align: center + :alt: + ++ Cuando los programas crecen, el código generalmente se vuelve más complejo ++ Una forma de gestionar esta complejidad es usar funciones ++ Te permiten separar acciones comunes, por lo que tu código es más + fácil de leer y más fácil de mantener diff --git a/293/_sources/lectures/TWP35/TWP35_1_en.rst.txt b/293/_sources/lectures/TWP35/TWP35_1_en.rst.txt new file mode 100644 index 0000000000..12fc934909 --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_1_en.rst.txt @@ -0,0 +1,19 @@ +Let's be more organized +======================= + + +.. image:: ../img/TWP35_001.jpeg + :height: 13.35cm + :width: 17.801cm + :align: center + :alt: + +.. image:: ../img/TWP35_002.jpeg + :height: 14.064cm + :width: 16.601cm + :align: center + :alt: + ++ When programs grow, the code usually becomes more complex ++ One way to manage this complexity is to use functions ++ They allow you to separate common actions, so your code is easier to read and easier to maintain \ No newline at end of file diff --git a/293/_sources/lectures/TWP35/TWP35_2.rst.txt b/293/_sources/lectures/TWP35/TWP35_2.rst.txt new file mode 100644 index 0000000000..b327974cc2 --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_2.rst.txt @@ -0,0 +1,60 @@ +Nueva sugerencia de programa +============================ + +Starbuzz no tiene granos +------------------------ + ++ El director de Starbuzz quiere una opción para comprar rápidamente, sin esperar + a que baje el precio ++ Al ejecutar el programa, te preguntaré si quieres comprar ahora o no ++ Si el usuario responde que sí, tomaré el precio actual y compraré ++ Si no, esperaré reducirlo a menos de 4.74 + +Nueva sugerencia de programa +---------------------------- + +.. activecode:: ac_l35_2 + :nocodelens: + :stdin: + + import urllib.request + + opcion = input("¿Quieres comprar ahora? (S/N)") + if opcion.lower() == "s": + pagina = urllib.request.urlopen("https://cors.bridged.cc/http://beans.itcarlow.ie/prices-loyalty.html") + texto = pagina.read() + # El método .find() devuelve la posición de la primer ocurrencia + # de la cadena que se le pase como parámetro. + donde = texto.find("$") + # el valor de donde es un número entero, representando + # la posición de $ en la cadena texto. + # Podemos obtener el precio si sacamos el pedazo de la cadena texto + # en donde se encuentra el precio. + inicio = donde + 1 + fin = inicio + 4 + # Obtenemos el precio con los índices correspondientes + precio = float(texto[inicio:fin]) + print("¡Comprar! Precio: %5.2f" % precio) + else: + precio = 99.99 + while precio >= 4.74: + pagina = urllib.request.urlopen("https://cors.bridged.cc/http://beans.itcarlow.ie/prices-loyalty.html") + texto = pagina.read() + donde = texto.find("$") + inicio = donde + 1 + fin = inicio + 4 + precio = float(texto[inicio:fin]) + print("¡Comprar! Precio: %5.2f" % precio) + + +Programa feo ... +---------------- + + ++ No duplique su código ... ++ Esto conduce a un exceso de código, lo que hace que el mantenimiento de su código + dificil ++ Intente reutilizar su código ++ Definiendo funciones reutilizaremos código ++ ¿Cuál es la diferencia? ++ Si tengo que cambiar algo, lo cambiaré en un solo lugar diff --git a/293/_sources/lectures/TWP35/TWP35_2_en.rst.txt b/293/_sources/lectures/TWP35/TWP35_2_en.rst.txt new file mode 100644 index 0000000000..b35fd072c6 --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_2_en.rst.txt @@ -0,0 +1,50 @@ +New program suggestion +============================ + +Starbuzz has no beans +------------------------ + ++ The director of Starbuzz wants an option to quickly buy without waiting + for the price to drop ++ When running the program, it will ask you if you want to buy now or not ++ If the user answers yes, it will take the current price and buy it ++ If not, it will wait until it drops below 4.74 + +New program suggestion +---------------------------- + +.. activecode:: ac_l35_2_en + :nocodelens: + :stdin: + + import urllib.request + + def buy(): + pagina = urllib.request.urlopen("https://cors.bridged.cc/http://beans.itcarlow.ie/prices-loyalty.html") + texto = pagina.read() + donde = texto.find("$") + inicio = donde + 1 + fin = inicio + 4 + precio = float(texto[inicio:fin]) + return precio + + opcion = input("Do you want to buy now? (Y/N)") + if opcion.lower() == "y": + precio = buy() + print("Buy now! Price: %5.2f" % precio) + else: + precio = 99.99 + while precio >= 4.74: + precio = buy() + print("Buy now! Price: %5.2f" % precio) + + +Ugly program... +---------------- + ++ Don't duplicate your code... ++ This leads to code bloat, making the maintenance of your code difficult ++ Try to reuse your code ++ By defining functions we will reuse code ++ What's the difference? ++ If I have to change something, I'll change it in one place. \ No newline at end of file diff --git a/293/_sources/lectures/TWP35/TWP35_3.rst.txt b/293/_sources/lectures/TWP35/TWP35_3.rst.txt new file mode 100644 index 0000000000..b6be2fb254 --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_3.rst.txt @@ -0,0 +1,53 @@ +Programa con funciones +====================== + +Funciones +--------- + ++ Las funciones son códigos compartibles ++ Defino un nombre y llamo a la función en todo el programa ++ La función debe estar definida antes de poder llamarla ++ Si desea devolver un valor al sujeto que llama la función, debe + usa el comando de retorno ``return`` + +Programa con funciones +---------------------- + +.. activecode:: ac_l35_3 + :nocodelens: + :stdin: + + import urllib.request + + + def capturar_precio(): + pagina = urllib.request.urlopen("https://cors.bridged.cc/http://beans.itcarlow.ie/prices-loyalty.html") + texto = pagina.read() + donde = texto.find("$") + inicio = donde + 1 + fin = inicio + 4 + return float(texto[inicio:fin]) + + + opcion = input("¿Quieres comprar ahora? (S/N)") + if opcion.lower() == "s": + precio = capturar_precio() + print("¡Comprar! Precio: %5.2f" % precio) + else: + precio = 99.99 + while precio >= 4.74: + precio = capturar_precio() + print("¡Comprar! Precio: %5.2f" % precio) + + +No hay preguntas tontas +----------------------- + + ++ ¿Es el comando de retorno lo mismo que imprimir? No, ``print()`` muestra algo en la pantalla, + mientras que ``return`` devuelve un valor para quien llamó a la función. ++ Si no hay ``return`` dentro de la función, ¿qué devuelve? Deuelve nada: ``None``. + ¿Debería ``return`` siempre aparecer al final de la función? No siempre, depende de la + lógica de la función ++ ¿Puede una función devolver más de un valor? Sí, incluidas listas o + diccionarios. diff --git a/293/_sources/lectures/TWP35/TWP35_3_en.rst.txt b/293/_sources/lectures/TWP35/TWP35_3_en.rst.txt new file mode 100644 index 0000000000..6e2f1ba719 --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_3_en.rst.txt @@ -0,0 +1,50 @@ +Program with functions +====================== + +Functions +--------- + ++ Functions are shareable codes ++ I define a name and call the function throughout the program ++ The function must be defined before it can be called ++ If you want to return a value to the subject that calls the function, you must use the ``return`` command + +Program with functions +---------------------- + +.. activecode:: ac_l35_3_en + :nocodelens: + :stdin: + + import urllib.request + + + def capture_price(): + page = urllib.request.urlopen("https://cors.bridged.cc/http://beans.itcarlow.ie/prices-loyalty.html") + text = page.read() + where = text.find("$") + start = where + 1 + end = start + 4 + return float(text[start:end]) + + + option = input("Do you want to buy now? (Y/N)") + if option.lower() == "y": + price = capture_price() + print("Buy! Price: %5.2f" % price) + else: + price = 99.99 + while price >= 4.74: + price = capture_price() + print("Buy! Price: %5.2f" % price) + + +There are no stupid questions +----------------------------- + ++ Is the return command the same as printing? No, ``print()`` shows something on the screen, + while ``return`` returns a value to the function caller. ++ If there is no ``return`` inside the function, what does it return? It returns nothing: ``None``. + Should ``return`` always appear at the end of the function? Not always, depends on the + logic of the function. ++ Can a function return more than one value? Yes, including lists or dictionaries. \ No newline at end of file diff --git a/293/_sources/lectures/TWP35/TWP35_4.rst.txt b/293/_sources/lectures/TWP35/TWP35_4.rst.txt new file mode 100644 index 0000000000..167273b61e --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_4.rst.txt @@ -0,0 +1,32 @@ +JSON +==== + +.. image:: ../img/TWP35_005.jpeg + :height: 16.402cm + :width: 25.442cm + :align: center + :alt: + + + ++ `JSON `_ ++ Idioma independiente ++ Pares de nombre / valor ++ Lista ordenada ++ Muy adoptado hoy ++ Alternativa a XML + + + XML es más detallado + + XML es menos legible + + +.. activecode:: ac_l35_4 + :nocodelens: + + import urllib.request + import json + + url = "http://api.icndb.com/jokes/random?limitTo=[nerdy]" + texto = urllib.request.urlopen(url).read() + data = json.loads(texto) + print(data["value"]["joke"]) diff --git a/293/_sources/lectures/TWP35/TWP35_4_en.rst.txt b/293/_sources/lectures/TWP35/TWP35_4_en.rst.txt new file mode 100644 index 0000000000..196dffbdd2 --- /dev/null +++ b/293/_sources/lectures/TWP35/TWP35_4_en.rst.txt @@ -0,0 +1,30 @@ +JSON +==== + +.. image:: ../img/TWP35_005.jpeg + :height: 16.402cm + :width: 25.442cm + :align: center + :alt: + ++ `JSON `_ ++ Language independent ++ Name / value pairs ++ Ordered list ++ Widely adopted today ++ Alternative to XML + + + XML is more detailed + + XML is less readable + + +.. activecode:: ac_l35_4_en + :nocodelens: + + import urllib.request + import json + + url = "http://api.icndb.com/jokes/random?limitTo=[nerdy]" + text = urllib.request.urlopen(url).read() + data = json.loads(text) + print(data["value"]["joke"]) \ No newline at end of file diff --git a/293/_sources/lectures/TWP35/toctree.rst.txt b/293/_sources/lectures/TWP35/toctree.rst.txt new file mode 100644 index 0000000000..ee67b80d59 --- /dev/null +++ b/293/_sources/lectures/TWP35/toctree.rst.txt @@ -0,0 +1,21 @@ +===================== +Revisión de Funciones +===================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP35_1.rst + TWP35_2.rst + TWP35_3.rst + TWP35_4.rst diff --git a/293/_sources/lectures/TWP35/toctree_en.rst.txt b/293/_sources/lectures/TWP35/toctree_en.rst.txt new file mode 100644 index 0000000000..b00dc8e2f5 --- /dev/null +++ b/293/_sources/lectures/TWP35/toctree_en.rst.txt @@ -0,0 +1,21 @@ +=============== +Function Review +=============== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP35_1_en.rst + TWP35_2_en.rst + TWP35_3_en.rst + TWP35_4_en.rst diff --git a/293/_sources/lectures/TWP37/TWP37_1.rst.txt b/293/_sources/lectures/TWP37/TWP37_1.rst.txt new file mode 100644 index 0000000000..b7e5dfaa0a --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_1.rst.txt @@ -0,0 +1,33 @@ +Campeonato de Surf de Codeville +=============================== + +.. image:: ../img/TWP37_001.jpeg + :height: 12.571cm + :width: 9.428cm + :align: center + :alt: + +.. image:: ../img/TWP37_002.jpeg + :height: 11.923cm + :width: 17.85cm + :align: center + :alt: + +.. image:: ../img/TWP37_003.jpeg + :height: 12.571cm + :width: 16.762cm + :align: center + :alt: + + +Encuentra la puntuación más alta +-------------------------------- + ++ Las puntuaciones están en el archivo ``surf.txt`` ++ ¡Selecciona la puntuación más alta para conocer al ganador! + +.. image:: ../img/TWP37_004.jpg + :height: 8.566cm + :width: 10.55cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP37/TWP37_1_en.rst.txt b/293/_sources/lectures/TWP37/TWP37_1_en.rst.txt new file mode 100644 index 0000000000..14425d9257 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_1_en.rst.txt @@ -0,0 +1,42 @@ +Surf Championship in Codeville +=============================== + +.. image:: ../img/TWP37_001.jpeg + :height: 12.571cm + :width: 9.428cm + :align: center + :alt: + +.. image:: ../img/TWP37_002.jpeg + :height: 11.923cm + :width: 17.85cm + :align: center + :alt: + +.. image:: ../img/TWP37_003.jpeg + :height: 12.571cm + :width: 16.762cm + :align: center + :alt: + + +Find the highest score +---------------------- + ++ The scores are in the ``surf.txt`` file ++ Choose the highest score to find out the winner! + +.. image:: ../img/TWP37_004.jpg + :height: 8.566cm + :width: 10.55cm + :align: center + :alt: + +Python code: + +.. code-block:: python + + with open('surf.txt') as f: + scores = [int(line.strip()) for line in f] + highest_score = max(scores) + print(f'The winner scored {highest_score} points!') \ No newline at end of file diff --git a/293/_sources/lectures/TWP37/TWP37_2.rst.txt b/293/_sources/lectures/TWP37/TWP37_2.rst.txt new file mode 100644 index 0000000000..cc1c47cab0 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_2.rst.txt @@ -0,0 +1,77 @@ +Leer el archivo ``surf.txt`` +============================ + +.. datafile:: surf.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_2a + :nocodelens: + :datafile: surf.txt + :stdin: + + archivo = open("surf.txt") + for linea in archivo: + print(linea.strip()) + archivo.close() + + +Fragmentador for +---------------- + +.. image:: ../img/TWP37_007.jpg + :height: 12.627cm + :width: 13cm + :align: center + :alt: + + +Descubre quién obtuvo la puntuación más alta +-------------------------------------------- + +.. image:: ../img/TWP37_008.jpg + :height: 14.824cm + :width: 11cm + :align: center + :alt: + + +El método ``split`` corta la cadena +----------------------------------- + +.. image:: ../img/TWP37_010.jpg + :height: 12.571cm + :width: 21.839cm + :align: center + :alt: + +.. image:: ../img/TWP37_011.jpg + :height: 12.571cm + :width: 21.839cm + :align: center + :alt: + + +Encontrando el 1º lugar +----------------------- + +.. activecode:: ac_l37_2b + :nocodelens: + :datafile: surf.txt + :stdin: + + archivo = open("surf.txt") + mayor = 0 + for linea in archivo: + nombre, puntos = linea.split() + if float(puntos) > mayor: + mayor = float(puntos) + archivo.close() + print(mayor) diff --git a/293/_sources/lectures/TWP37/TWP37_2_en.rst.txt b/293/_sources/lectures/TWP37/TWP37_2_en.rst.txt new file mode 100644 index 0000000000..07fff7bec5 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_2_en.rst.txt @@ -0,0 +1,77 @@ +Reading the file ``surf_en.txt`` +================================ + +.. datafile:: surf_en.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_2a_en + :nocodelens: + :datafile: surf_en.txt + :stdin: + + file = open("surf_en.txt") + for line in file: + print(line.strip()) + file.close() + + +For loop breakdown +------------------ + +.. image:: ../img/TWP37_007.jpg + :height: 12.627cm + :width: 13cm + :align: center + :alt: + + +Find out who got the highest score +----------------------------------- + +.. image:: ../img/TWP37_008.jpg + :height: 14.824cm + :width: 11cm + :align: center + :alt: + + +The ``split`` method breaks up the string +----------------------------------------- + +.. image:: ../img/TWP37_010.jpg + :height: 12.571cm + :width: 21.839cm + :align: center + :alt: + +.. image:: ../img/TWP37_011.jpg + :height: 12.571cm + :width: 21.839cm + :align: center + :alt: + + +Finding the 1st place +--------------------- + +.. activecode:: ac_l37_2b_en + :nocodelens: + :datafile: surf_en.txt + :stdin: + + file = open("surf_en.txt") + highest_score = 0 + for line in file: + name, score = line.split() + if float(score) > highest_score: + highest_score = float(score) + file.close() + print(highest_score) \ No newline at end of file diff --git a/293/_sources/lectures/TWP37/TWP37_3.rst.txt b/293/_sources/lectures/TWP37/TWP37_3.rst.txt new file mode 100644 index 0000000000..01778c2fbb --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_3.rst.txt @@ -0,0 +1,50 @@ +El marcador... +=============== + + +.. image:: ../img/TWP37_014.jpg + :height: 10.906cm + :width: 21.021cm + :align: center + :alt: + + +El seguimiento de 3 puntajes es complicado +------------------------------------------ + +.. datafile:: surf2.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_3 + :nocodelens: + :datafile: surf2.txt + :stdin: + + archivo = open("surf2.txt") + primero = 0 + segundo = 0 + tercero = 0 + for linea in archivo: + nombre, puntos = linea.split() + if float(puntos) > primero: + tercero = segundo + segundo = primero + primero = float(puntos) + elif float(puntos) > segundo: + tercero = segundo + segundo = float(puntos) + elif float(puntos) > tercero: + tercero = float(puntos) + archivo.close() + + print("%.2f" % primero) + print("%.2f" % segundo) + print("%.2f" % tercero) diff --git a/293/_sources/lectures/TWP37/TWP37_3_en.rst.txt b/293/_sources/lectures/TWP37/TWP37_3_en.rst.txt new file mode 100644 index 0000000000..4d84e54fa0 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_3_en.rst.txt @@ -0,0 +1,50 @@ +The marker... +=============== + + +.. image:: ../img/TWP37_014.jpg + :height: 10.906cm + :width: 21.021cm + :align: center + :alt: + + +Tracking 3 scores is complicated +------------------------------------------ + +.. datafile:: surf2_en.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_3_en + :nocodelens: + :datafile: surf2_en.txt + :stdin: + + file = open("surf2_en.txt") + first = 0 + second = 0 + third = 0 + for line in file: + name, points = line.split() + if float(points) > first: + third = second + second = first + first = float(points) + elif float(points) > second: + third = second + second = float(points) + elif float(points) > third: + third = float(points) + file.close() + + print("%.2f" % first) + print("%.2f" % second) + print("%.2f" % third) \ No newline at end of file diff --git a/293/_sources/lectures/TWP37/TWP37_4.rst.txt b/293/_sources/lectures/TWP37/TWP37_4.rst.txt new file mode 100644 index 0000000000..0a60779f31 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_4.rst.txt @@ -0,0 +1,48 @@ +Ordenar la lista sería mejor +============================ + +.. image:: ../img/TWP37_016.jpg + :height: 12.09cm + :width: 20.531cm + :align: center + :alt: + + +Ordenar es más fácil en la memoria +---------------------------------- + ++ Los datos del disco son persistentes: si tira del cable de la toma de corriente, la computadora no olvidará la información grabada en el disco. ++ Los datos en la memoria son mucho más rápidos, pero no persistentes: los datos en la memoria desaparecen cuando sale de su programa o cuando el la computadora está apagada. ++ Compensación de diseño: persistencia x velocidad. + + +Primero: lea los datos en la memoria +------------------------------------ + +.. image:: ../img/TWP37_017.jpg + :height: 9.55cm + :width: 21.457cm + :align: center + :alt: + + +Wow, usemos un tren de datos +---------------------------- + ++ Matriz, lista, vector son nombres comunes para un lote completo de datos. ++ Solo necesito una sola variable para todo el tren de datos. + + +.. image:: ../img/TWP37_018.jpg + :height: 7.4cm + :width: 9.632cm + :align: center + :alt: + + +Volviendo al surf ... +--------------------- + ++ Podemos crear una lista ``puntuaciones``. ++ Para insertar cada nueva puntuación, use ``.append()`` ++ El mejor puesto serán las ``puntuaciones[0]``, ``puntuaciones[1]`` y ``puntuaciones[2]``. diff --git a/293/_sources/lectures/TWP37/TWP37_4_en.rst.txt b/293/_sources/lectures/TWP37/TWP37_4_en.rst.txt new file mode 100644 index 0000000000..896f653c26 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_4_en.rst.txt @@ -0,0 +1,48 @@ +Sorting the List would be Better +================================= + +.. image:: ../img/TWP37_016.jpg + :height: 12.09cm + :width: 20.531cm + :align: center + :alt: + + +Sorting is Easier in Memory +---------------------------- + ++ Disk data is persistent: if you pull the power cord, the computer won't forget the information saved on the disk. ++ Data in memory is much faster, but not persistent: data in memory disappears when you exit your program or when the computer is turned off. ++ Design trade-off: persistence x speed. + + +First: Read Data into Memory +---------------------------- + +.. image:: ../img/TWP37_017.jpg + :height: 9.55cm + :width: 21.457cm + :align: center + :alt: + + +Wow, Let's Use a Data Train +---------------------------- + ++ Array, list, vector are common names for a complete set of data. ++ I only need a single variable for the entire data train. + + +.. image:: ../img/TWP37_018.jpg + :height: 7.4cm + :width: 9.632cm + :align: center + :alt: + + +Back to Surfing ... +------------------- + ++ We can create a list ``scores``. ++ To insert each new score, use ``.append()``. ++ The top positions will be ``scores[0]``, ``scores[1]``, and ``scores[2]``. \ No newline at end of file diff --git a/293/_sources/lectures/TWP37/TWP37_5.rst.txt b/293/_sources/lectures/TWP37/TWP37_5.rst.txt new file mode 100644 index 0000000000..00f087c914 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_5.rst.txt @@ -0,0 +1,84 @@ +Nueva puntuación +================ + +.. datafile:: surf3.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_5a + :nocodelens: + :datafile: surf3.txt + :stdin: + + archivo = open("surf3.txt") + puntuaciones = [] + + for linea in archivo: + nombre, puntos = linea.split() + puntuaciones.append(float(puntos)) + archivo.close() + + print(f"1. {puntuaciones[0]:.2f}") + print(f"2. {puntuaciones[1]:.2f}") + print(f"3. {puntuaciones[2]:.2f}") + + +.. image:: ../img/TWP37_021.jpg + :height: 10.006cm + :width: 12.699cm + :align: center + :alt: + + +Ordenar en orden descendente +---------------------------- + +.. image:: ../img/TWP37_022.jpg + :height: 12.571cm + :width: 22.825cm + :align: center + :alt: + + +Métodos ``sort`` y ``reverse`` +------------------------------ + ++ El método ``sort`` ordena los datos. ++ El uso de ``reverse`` para mantenerlos en orden descendente. ++ Es más inteligente usar ``puntuaciones.sort(reverse = True)`` + + +Finalmente las posiciones correctas +----------------------------------- + +.. activecode:: ac_l37_5b + :nocodelens: + :datafile: surf3.txt + :stdin: + + archivo = open("surf3.txt") + puntuaciones = [] + + for linea in archivo: + nombre, puntos = linea.split() + puntuaciones.append(float(puntos)) + archivo.close() + + puntuaciones.sort(reverse = True) + + print(f"1. {puntuaciones[0]:.2f}") + print(f"2. {puntuaciones[1]:.2f}") + print(f"3. {puntuaciones[2]:.2f}") + +.. image:: ../img/TWP37_025.jpg + :height: 7.724cm + :width: 16.645cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP37/TWP37_5_en.rst.txt b/293/_sources/lectures/TWP37/TWP37_5_en.rst.txt new file mode 100644 index 0000000000..549eea4b4f --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_5_en.rst.txt @@ -0,0 +1,84 @@ +New Score +========= + +.. datafile:: surf3_en.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_5a_en + :nocodelens: + :datafile: surf3_en.txt + :stdin: + + file = open("surf3_en.txt") + scores = [] + + for line in file: + name, points = line.split() + scores.append(float(points)) + file.close() + + print(f"1. {scores[0]:.2f}") + print(f"2. {scores[1]:.2f}") + print(f"3. {scores[2]:.2f}") + + +.. image:: ../img/TWP37_021.jpg + :height: 10.006cm + :width: 12.699cm + :align: center + :alt: + + +Sorting in decreasing order +---------------------------- + +.. image:: ../img/TWP37_022.jpg + :height: 12.571cm + :width: 22.825cm + :align: center + :alt: + + +``sort`` and ``reverse`` methods +-------------------------------- + ++ The ``sort`` method sorts the data. ++ The use of ``reverse`` keeps them in descending order. ++ It is smarter to use ``scores.sort(reverse=True)`` + + +Finally the correct positions +----------------------------- + +.. activecode:: ac_l37_5b_en + :nocodelens: + :datafile: surf3_en.txt + :stdin: + + file = open("surf3_en.txt") + scores = [] + + for line in file: + name, points = line.split() + scores.append(float(points)) + file.close() + + scores.sort(reverse=True) + + print(f"1. {scores[0]:.2f}") + print(f"2. {scores[1]:.2f}") + print(f"3. {scores[2]:.2f}") + +.. image:: ../img/TWP37_025.jpg + :height: 7.724cm + :width: 16.645cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP37/TWP37_6.rst.txt b/293/_sources/lectures/TWP37/TWP37_6.rst.txt new file mode 100644 index 0000000000..99b27cf551 --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_6.rst.txt @@ -0,0 +1,102 @@ +¿Cuáles son los nombres de los ganadores? +========================================= + +.. image:: ../img/TWP37_026.png + :height: 7.724cm + :width: 16.645cm + :align: center + :alt: + + +Usando otra lista +----------------- + ++ Para saberlo podemos usar dos listas. ++ La lista ``nombres`` y la lista ``puntuaciones`` para guardar los nombres y las puntuaciones obtenidas por los participantes respectivamente. + +.. datafile:: surf4.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_6a + :nocodelens: + :datafile: surf4.txt + :stdin: + + archivo = open("surf4.txt") + puntuaciones = [] + nombres = [] + + for linea in archivo: + nombre, puntos = linea.split() + puntuaciones.append(float(puntos)) + nombres.append(nombre) + archivo.close() + + puntuaciones.sort(reverse = True) + nombres.sort(reverse = True) + + print(f"1. {nombres[0]} {puntuaciones[0]:.2f}") + print(f"2. {nombres[1]} {puntuaciones[1]:.2f}") + print(f"3. {nombres[2]} {puntuaciones[2]:.2f}") + + +¡Pero estos datos son incorrectos! +---------------------------------- + ++ Debe haber un problema porque ¡Zack es realmente malo! ++ ¿Qué fue lo sucedió? ++ Ordenando la lista ``nombres`` de forma decreciente el carácter ``'Z'`` termina siendo el primero. ++ Se pierde la correspondencia de las puntuaciones y los nombres de los participantes. ++ Necesario otra estructura de datos para no perder la correspondencia. + + +Necesitamos unir las listas +--------------------------- + +.. image:: ../img/TWP37_027.png + :height: 11.724cm + :width: 17.645cm + :align: center + :alt: + + +Usando y ordenando un diccionario +--------------------------------- + ++ Usando un diccionario y ver todos sus elementos de forma iterativa. + +.. codelens:: cl_l37_6 + + puntuaciones = {} + puntuaciones[9.12] = "Juan" + puntuaciones[7.21] = "Zack" + + for participante in sorted(puntuaciones, reverse=True): + print(f"{puntuaciones[participante]} {participante:.2f}") + + ++ Usando un diccionario para el campeonato. + +.. activecode:: ac_l37_6b + :nocodelens: + :datafile: surf4.txt + :stdin: + + archivo = open("surf4.txt") + puntuaciones = {} + + for linea in archivo: + nombre, puntos = linea.split() + puntuaciones[float(puntos)] = nombre + archivo.close() + + for participante in sorted(puntuaciones, reverse=True): + print(f"{puntuaciones[participante]} obtuvo un puntaje de {participante:.2f}") diff --git a/293/_sources/lectures/TWP37/TWP37_6_en.rst.txt b/293/_sources/lectures/TWP37/TWP37_6_en.rst.txt new file mode 100644 index 0000000000..0684729d2e --- /dev/null +++ b/293/_sources/lectures/TWP37/TWP37_6_en.rst.txt @@ -0,0 +1,102 @@ +What are the names of the winners? +================================== + +.. image:: ../img/TWP37_026.png + :height: 7.724cm + :width: 16.645cm + :align: center + :alt: + + +Using another list +------------------ + ++ We can use two lists to find out. ++ The ``names`` and ``scores`` lists to save the names and scores obtained by the participants respectively. + +.. datafile:: surf4_en.txt + :hide: + + Johny 8.65 + Juan 9.12 + Joseph 8.45 + Stacey 7.81 + Aideen 8.05 + Zack 7.21 + Aaron 8.31 + +.. activecode:: ac_l37_6a_en + :nocodelens: + :datafile: surf4_en.txt + :stdin: + + file = open("surf4_en.txt") + scores = [] + names = [] + + for line in file: + name, points = line.split() + scores.append(float(points)) + names.append(name) + file.close() + + scores.sort(reverse=True) + names.sort(reverse=True) + + print(f"1. {names[0]} {scores[0]:.2f}") + print(f"2. {names[1]} {scores[1]:.2f}") + print(f"3. {names[2]} {scores[2]:.2f}") + + +But these data are incorrect! +----------------------------- + ++ There must be a problem because Zack is really bad! ++ What happened? ++ By sorting the ``names`` list in decreasing order, the character ``'Z'`` ends up being the first. ++ The correspondence between scores and the names of the participants is lost. ++ Another data structure is needed to avoid losing the correspondence. + + +We need to join the lists +------------------------- + +.. image:: ../img/TWP37_027.png + :height: 11.724cm + :width: 17.645cm + :align: center + :alt: + + +Using and sorting a dictionary +------------------------------- + ++ Using a dictionary and seeing all its elements iteratively. + +.. codelens:: cl_l37_6_en + + scores = {} + scores[9.12] = "Juan" + scores[7.21] = "Zack" + + for participant in sorted(scores, reverse=True): + print(f"{scores[participant]} {participant:.2f}") + + ++ Using a dictionary for the championship. + +.. activecode:: ac_l37_6b_en + :nocodelens: + :datafile: surf4_en.txt + :stdin: + + file = open("surf4_en.txt") + scores = {} + + for line in file: + name, points = line.split() + scores[float(points)] = name + file.close() + + for participant in sorted(scores, reverse=True): + print(f"{scores[participant]} obtained a score of {participant:.2f}") \ No newline at end of file diff --git a/293/_sources/lectures/TWP37/toctree.rst.txt b/293/_sources/lectures/TWP37/toctree.rst.txt new file mode 100644 index 0000000000..898ff32b92 --- /dev/null +++ b/293/_sources/lectures/TWP37/toctree.rst.txt @@ -0,0 +1,23 @@ +=========================================== +Revisión de Archivos, Listas y Diccionarios +=========================================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP37_1.rst + TWP37_2.rst + TWP37_3.rst + TWP37_4.rst + TWP37_5.rst + TWP37_6.rst diff --git a/293/_sources/lectures/TWP37/toctree_en.rst.txt b/293/_sources/lectures/TWP37/toctree_en.rst.txt new file mode 100644 index 0000000000..8810c5aa99 --- /dev/null +++ b/293/_sources/lectures/TWP37/toctree_en.rst.txt @@ -0,0 +1,23 @@ +================================= +File, List, and Dictionary Review +================================= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP37_1_en.rst + TWP37_2_en.rst + TWP37_3_en.rst + TWP37_4_en.rst + TWP37_5_en.rst + TWP37_6_en.rst diff --git a/293/_sources/lectures/TWP38/TWP38_1.rst.txt b/293/_sources/lectures/TWP38/TWP38_1.rst.txt new file mode 100644 index 0000000000..e86fd9ae79 --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_1.rst.txt @@ -0,0 +1,27 @@ +¿Qué es un programa? +==================== + ++ Un conjunto detallado de instrucciones, paso a paso, que le dice a la + computadora qué hacer. ++ Si cambiamos el programa, la computadora hará algo diferente ++ La computadora permanece igual, pero el programa ha cambiado ++ Los programas se ejecutan ++ El software (programas) controla el hardware ++ El proceso de creación de software se llama programación ++ Un algoritmo es la receta, paso a paso, que resuelve un problema computacional + + +Lenguajes de programación +------------------------- ++ Los idiomas de bajo nivel son los más cercanos a la máquina ++ Ensamblador: + + + Cargue el número de variables A en la CPU + + Cargue el número de variables B en la CPU + + Agregar los dos números en la CPU + + Almacenar el resultado en la variable C ++ Comando original en lenguaje de alto nivel: C = A + B ++ Los compiladores convierten el lenguaje de alto nivel al lenguaje de + máquina informática específica ++ Los intérpretes analizan y ejecutan el programa instrucción por + instrucción del lenguaje de máquina diff --git a/293/_sources/lectures/TWP38/TWP38_1_en.rst.txt b/293/_sources/lectures/TWP38/TWP38_1_en.rst.txt new file mode 100644 index 0000000000..dbb38d04ee --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_1_en.rst.txt @@ -0,0 +1,22 @@ +What is a program? +==================== + ++ A detailed set of instructions, step by step, that tells the computer what to do. ++ If we change the program, the computer will do something different ++ The computer remains the same, but the program has changed. ++ Programs are executed. ++ Software (programs) controls hardware. ++ The process of creating software is called programming. ++ An algorithm is a step-by-step recipe for solving a computational problem. + +Programming languages +------------------------- ++ Low-level languages are the closest to the machine: + + Assembler: + + Load the number of variables A into the CPU. + + Load the number of variables B into the CPU. + + Add the two numbers in the CPU. + + Store the result in variable C. ++ Original high-level language command: C = A + B. ++ Compilers convert high-level language to specific computer machine language. ++ Interpreters parse and execute the program instruction by instruction in the computer's machine language. \ No newline at end of file diff --git a/293/_sources/lectures/TWP38/TWP38_2.rst.txt b/293/_sources/lectures/TWP38/TWP38_2.rst.txt new file mode 100644 index 0000000000..550c3c4b5e --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_2.rst.txt @@ -0,0 +1,61 @@ +Python +====== + +.. codelens:: cl_l38_2a + + print("hola mundo!") + print(2 + 3) + print("2 + 3 = ", 2 + 3) + + ++ Por lo general, queremos repetir una serie de comandos varias veces ++ Una forma de hacer esto es usar una función + +.. codelens:: cl_l38_2b + + def amo_dos_puntos(): + print("Yo amo:!") + print('Dos puntos == ":"') + + + amo_dos_puntos() + + ++ ¡No olvide los paréntesis cuando llames a la función! ++ Si olvida los paréntesis, python devolverá la dirección en + memoria donde se encuentra definida la función. + +.. codelens:: cl_l38_2c + + def amo_dos_puntos(): + print("Yo amo:!") + print('Dos puntos == ":"') + + + print(amo_dos_puntos) + print(print) + + ++ Podemos poner parámetros en una función + +.. codelens:: cl_l38_2d + + def suma(a, b): + return a + b + + + print(suma("aguacate", "jabuticaba")) + print(suma(2, 3)) + print(suma(3.14, 2.71)) + + ++ Las funciones dejan de existir en cuanto sale del intérprete + Python ++ Por lo tanto, los programas generalmente se componen de módulos, que son + archivos guardados en el disco ++ Un módulo es un archivo de texto que contiene un programa de Python ++ Puede editar los módulos en un entorno de desarrollo, que + resalta palabras reservadas, realiza identificación automática, etc. ++ Guardamos un programa llamado ``caos.py`` ++ No olvides la extensión ``.py`` ++ Podemos ejecutar el programa con el botón de ``Run`` diff --git a/293/_sources/lectures/TWP38/TWP38_2_en.rst.txt b/293/_sources/lectures/TWP38/TWP38_2_en.rst.txt new file mode 100644 index 0000000000..82deb503d7 --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_2_en.rst.txt @@ -0,0 +1,60 @@ +Python +====== + +.. codelens:: cl_l38_2a_en + + print("hello world!") + print(2 + 3) + print("2 + 3 = ", 2 + 3) + + ++ Usually, we want to repeat a series of commands several times ++ One way to do this is to use a function + +.. codelens:: cl_l38_2b_en + + def love_colon(): + print("I love:") + print('Colon == ":"') + + + love_colon() + + ++ Don't forget parentheses when calling the function! ++ If you forget the parentheses, Python will return the memory address + where the function is defined. + +.. codelens:: cl_l38_2c_en + + def love_colon(): + print("I love:") + print('Colon == ":"') + + + print(love_colon) + print(print) + + ++ We can put parameters in a function + +.. codelens:: cl_l38_2d_en + + def add(a, b): + return a + b + + + print(add("avocado", "jabuticaba")) + print(add(2, 3)) + print(add(3.14, 2.71)) + + ++ Functions cease to exist as soon as you exit the Python interpreter ++ Hence, programs generally consist of modules, which are + files stored on disk ++ A module is a text file containing a Python program ++ You can edit modules in a development environment, which + highlights reserved words, performs automatic indentation, etc. ++ We save a program called ``chaos.py`` ++ Don't forget the ``.py`` extension ++ We can run the program with the "Run" button. \ No newline at end of file diff --git a/293/_sources/lectures/TWP38/TWP38_3.rst.txt b/293/_sources/lectures/TWP38/TWP38_3.rst.txt new file mode 100644 index 0000000000..2234f1d299 --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_3.rst.txt @@ -0,0 +1,50 @@ +Construcción del archivo +======================== + ++ Las líneas que comienzan con **"#"** se llaman comentarios ++ Están destinados a ser leídos por humanos y Python los ignora ++ Python omite todo el texto desde el **"#"** hasta el final de la línea + +.. code-block:: python + + # Archivo caos.py + # Un programa que ilustra la Teoria del caos + ++ ``x`` es un ejemplo de una variable ++ En ``x`` asignaremos un valor al que se puede hacer referencia más adelante ++ Se mostrará el mensaje entre comillas y la respuesta se almacenará en ``x`` + +.. code-block:: python + + x = eval(input("Ingrese un número entre 0 y 1:")) + ++ Hay comandos de bucle o ciclos como el comando ``for`` ++ Un bucle o ciclo se usa para repetir un bloque de código varias veces ++ En este ejemplo, el siguiente bloque se repetirá 10 veces + +.. code-block:: python + + for i in range(10): + ++ Llamamos **sangría** a los espacios al comienzo de la línea ++ En Python, la sangría delimita el bloque que se ejecutará ++ El cálculo ``3.9 * x * (1-x)`` se realizará en la CPU y se asignará a la variable + ``x`` + +Resultado +--------- + +.. activecode:: ac_l38_3 + :language: python3 + :python3_interpreter: brython + + # Archivo caos.py + # Un programa que ilustra la Teoria del caos + print("Este programa ilustra el comportamiento caótico.") + x = eval(input("Ingrese un número entre 0 y 1:")) + for i in range(10): + x = 3.9 * x * (1 - x) + print("%2.3f" % x) + + ++ El programa de caos devuelve valores muy diferentes, incluso cuando la entrada es similar diff --git a/293/_sources/lectures/TWP38/TWP38_3_en.rst.txt b/293/_sources/lectures/TWP38/TWP38_3_en.rst.txt new file mode 100644 index 0000000000..42a94d74ba --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_3_en.rst.txt @@ -0,0 +1,50 @@ +File construction +======================== + ++ Lines that start with **"#"** are called comments ++ They are intended to be read by humans and Python ignores them ++ Python skips all text from the **"#"** to the end of the line + +.. code-block:: python + + # File chaos.py + # A program that illustrates the Chaos Theory + ++ ``x`` is an example of a variable ++ We will assign a value to ``x`` that can be referred to later ++ The message in quotes will be displayed and the response will be stored in ``x`` + +.. code-block:: python + + x = eval(input("Enter a number between 0 and 1:")) + ++ There are loop or cycle commands such as the ``for`` command ++ A loop or cycle is used to repeat a block of code several times ++ In this example, the following block will be repeated 10 times + +.. code-block:: python + + for i in range(10): + ++ We call **indentation** to the spaces at the beginning of the line ++ In Python, indentation delimits the block that will be executed ++ The calculation ``3.9 * x * (1-x)`` will be performed on the CPU and assigned to the variable + ``x`` + +Result +------ + +.. activecode:: ac_l38_3_en + :language: python3 + :python3_interpreter: brython + + # File chaos.py + # A program that illustrates the Chaos Theory + print("This program illustrates chaotic behavior.") + x = eval(input("Enter a number between 0 and 1:")) + for i in range(10): + x = 3.9 * x * (1 - x) + print("%2.3f" % x) + + ++ The chaos program returns very different values, even when the input is similar. \ No newline at end of file diff --git a/293/_sources/lectures/TWP38/TWP38_4.rst.txt b/293/_sources/lectures/TWP38/TWP38_4.rst.txt new file mode 100644 index 0000000000..8d3cc42ff9 --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_4.rst.txt @@ -0,0 +1,50 @@ +Ejercicio +========= + ++ Cambie el programa anterior para que pueda ingresar un valor e ingresar correr por + n veces en lugar del valor 10. Asigne ese valor a una variable llamada ``n``. ++ **Debe llamar su variable n para que su programa pase la prueba, de lo contrario dará error.** + +.. activecode:: ac_l38_4 + :language: python3 + :python3_interpreter: brython + + # Archivo caos.py + # Un programa que ilustra la Teoria del caos + print("Este programa ilustra el comportamiento caótico.") + x = eval(input("Ingrese un número entre 0 y 1:")) + for i in range(10): + x = 3.9 * x * (1 - x) + print("%2.3f" % x) + + ==== + import unittest + + class myTests(unittest.TestCase): + + def testOne(self): + + self.assertEqual(n, i+1, "El número de ciclos no es el especificado por el usuario") + + myTests().testOne() + print("-------------------------------------") + print("Has aprobado el 100% de las pruebas.") + +Resumen +------- + ++ La descripción de una secuencia de pasos para resolver un problema se llama + algoritmo computacional. ++ Los algoritmos son programas (software) que determinan que hará + la computadora (hardware). ++ El proceso de creación de software se llama programación. + + +Recuerde +-------- + ++ Los lenguajes de programación tienen una sintaxis formal ++ Las computadoras solo entienden el lenguaje de máquina ++ Python es un lenguaje interpretado de alto nivel ++ El intérprete de Python convierte los comandos instrucción por instrucción + a lenguaje máquina diff --git a/293/_sources/lectures/TWP38/TWP38_4_en.rst.txt b/293/_sources/lectures/TWP38/TWP38_4_en.rst.txt new file mode 100644 index 0000000000..958a508885 --- /dev/null +++ b/293/_sources/lectures/TWP38/TWP38_4_en.rst.txt @@ -0,0 +1,47 @@ +Exercise +========= + ++ Modify the previous program so that it can input a value and run for n times instead of the value 10. Assign that value to a variable named ``n``. ++ **You must call your variable n for your program to pass the test, otherwise it will fail.** + +.. activecode:: ac_l38_4_en + :language: python3 + :python3_interpreter: brython + + # File caos.py + # A program that illustrates the Chaos Theory + print("This program illustrates chaotic behavior.") + x = eval(input("Enter a number between 0 and 1:")) + # Modified code + n = eval(input("Enter the number of times to run the program:")) + for i in range(n): + x = 3.9 * x * (1 - x) + print("%2.3f" % x) + + ==== + import unittest + + class myTests(unittest.TestCase): + + def testOne(self): + # Modified code + self.assertEqual(n, i+1, "The number of cycles is not specified by the user") + + myTests().testOne() + print("-------------------------------------") + print("You have passed 100% of the tests.") + +Summary +------- + ++ The description of a sequence of steps to solve a problem is called a computational algorithm. ++ Algorithms are programs (software) that determine what the computer (hardware) will do. ++ The process of creating software is called programming. + +Remember +-------- + ++ Programming languages have a formal syntax. ++ Computers only understand machine language. ++ Python is a high-level interpreted language. ++ The Python interpreter converts instructions command by command into machine language. \ No newline at end of file diff --git a/293/_sources/lectures/TWP38/toctree.rst.txt b/293/_sources/lectures/TWP38/toctree.rst.txt new file mode 100644 index 0000000000..f8df7ecaa5 --- /dev/null +++ b/293/_sources/lectures/TWP38/toctree.rst.txt @@ -0,0 +1,21 @@ +================== +Revisión general 2 +================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP38_1.rst + TWP38_2.rst + TWP38_3.rst + TWP38_4.rst diff --git a/293/_sources/lectures/TWP38/toctree_en.rst.txt b/293/_sources/lectures/TWP38/toctree_en.rst.txt new file mode 100644 index 0000000000..4318550627 --- /dev/null +++ b/293/_sources/lectures/TWP38/toctree_en.rst.txt @@ -0,0 +1,21 @@ +================ +General review 2 +================ + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP38_1_en.rst + TWP38_2_en.rst + TWP38_3_en.rst + TWP38_4_en.rst diff --git a/293/_sources/lectures/TWP40/TWP40_1.rst.txt b/293/_sources/lectures/TWP40/TWP40_1.rst.txt new file mode 100644 index 0000000000..ad93c2c5db --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_1.rst.txt @@ -0,0 +1,55 @@ +El proceso de desarrollo de software +==================================== + ++ Ejecutar programas creados por otros es relativamente simple ++ Lo difícil es comenzar a crear tus propios programas ++ Las computadoras son muy estrictas y hay muchos detalles ++ Entonces es necesario ser muy sistemático + +Pasos en el proceso de desarrollo de software +--------------------------------------------- + ++ Analizar el problema: + + Comprender exactamente ¿cuál es el problema a resolver? + + Problema bien definido, medio problema resuelto. + ++ Especificación de lo que hará el programa: + + Describe exactamente lo que hará tu programa. + + En esta etapa, no debería preocuparme sobre ¿cómo voy a hacer mi programa?, pero mas decidir exactamente ¿qué hará? + + ¿Cuáles son las entradas y salidas del programa? + ++ Diseñar el programa: + + Formular la estructura general del programa. + + Podemos usar pseudocódigo en este paso. + ++ Implementar el programa: + + Diseñar algunas pruebas para validar tu programa. + + Traduce el proyecto a cualquier lenguaje de programación. + + En este curso usaremos Python. + +Ejemplo: convertidor de temperatura Fahrenheit a Celsius +-------------------------------------------------------- + ++ Análisis del problema: + + Dada una temperatura en grados *Fahrenheit*, obtenga la conversión en Celsius. + ++ Especificación de lo que hará el programa: + + Entrada: temperatura en Fahrenheit + + Salida: temperatura en grados Celsius + + Salida: 5 * (F-32) / 9 + ++ Diseñar ¿cómo funcionará el programa?: + + Leer el valor de temperatura en Fahrenheit. + + Convertir el valor usando la fórmula ``5 * (F-32) / 9`` + + Imprimir el valor convertido. + ++ Implementación del problema: + + Pruebas: 32F = 0C y 100F = 37.8C + +.. activecode:: ac_l40_1 + :nocodelens: + :stdin: + + F = float(input("Fahrenheit: ")) + C = 5 * (F - 32) / 9 + print("Celsius: %2.1f" % C) diff --git a/293/_sources/lectures/TWP40/TWP40_10.rst.txt b/293/_sources/lectures/TWP40/TWP40_10.rst.txt new file mode 100644 index 0000000000..8be6c9ca36 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_10.rst.txt @@ -0,0 +1,70 @@ +Ejercicio +========= + ++ Queremos desarrollar un programa que determine el valor futuro de una inversión, dado el valor inicial y la tasa de interés ++ Seguimos los pasos para el desarrollo. + + ++ Análisis: + + El dinero inicial genera una tasa de interés anual + + ¿Cuánto valdrá en 10 años? + + Entrada: monto inicial, tasa de interés + + Salida: valor en 10 años + ++ Especificación: + + El usuario ingresa la cantidad inicial invertida + + El usuario ingresa la tasa de interés anual + + Valor de la fórmula matemática financiera * (1 + interés) + ++ Diseño: + + Ingrese el monto de inversión inicial. + + Ingrese la tasa de interés. + + Repite 10 veces: + + valor inicial = valor inicial * (1 + tasa de interés) + + Imprime el valor actualizado. + ++ Implementación: + + Valores de prueba: + + 1000 dolares de inversión y 3% la tasa de interés anual + + 1000 dolares de inversión y 10% la tasa de interés anual + +.. activecode:: ac_l40_10 + :nocodelens: + :stdin: + + valor = float(input("Cantidad inicial invertida: ")) + tasa = float(input("Tasa de interés anual: ")) + for i in range(10): + valor = valor * (1 + tasa / 100) + print("Valor después de 10 años: %5.2f" % valor) + + +Preguntas frecuentes +-------------------- +.. mchoice:: feedback_l40_10_1 + :random: + :answer_a: nos ayuda a construir el producto correcto sin desperdicios ni redundancias + :feedback_a: A menudo tiene sentido escribir la prueba primero y luego escribir tanto código como sea necesario para permitir que la prueba pase. + :answer_b: Hace que el código se ejecute más rápido. + :feedback_b: es incorrecto porque la definición de pruebas no afecta directamente la velocidad del código. + :answer_c: Permite al programador escribir menos código. + :feedback_c: es incorrecto porque escribir pruebas en realidad requiere que se escriba más código. + :answer_d: No es necesario para una buena programación. + :feedback_d: es incorrecto porque definir pruebas es un aspecto importante de las buenas prácticas de programación. + :correct: a + + Por qué definir algunas pruebas antes de la implementación es una buena práctica de programación? + +.. mchoice:: feedback_l40_10_2 + :random: + :answer_a: Permite probar el flujo lógico del programa antes de codificarlo. + :feedback_a: Escribir pseudocódigo en la etapa de diseño brinda varios beneficios, incluida la capacidad de probar la lógica y la estructura del programa antes de escribir cualquier código real. + :answer_b: Ahorra tiempo y esfuerzo en la codificación más adelante. + :feedback_b: es incorrecto porque escribir pseudocódigo requiere tiempo y esfuerzo, pero es una inversión que vale la pena en la etapa de diseño. + :answer_c: Ayuda a identificar errores de sintaxis en el código. + :feedback_c: Esto ayuda a identificar errores lógicos, lagunas y lagunas en el diseño del programa, lo que ahorra tiempo y esfuerzo a largo plazo. + :answer_d: Facilita la depuración del código. + :feedback_d: Esto ayuda a identificar errores lógicos, lagunas y lagunas en el diseño del programa, lo que ahorra tiempo y esfuerzo a largo plazo. + :correct: a + + Cuál es la ventaja de escribir pseudocódigo en la etapa de diseño? diff --git a/293/_sources/lectures/TWP40/TWP40_10_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_10_en.rst.txt new file mode 100644 index 0000000000..7a53e78ac5 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_10_en.rst.txt @@ -0,0 +1,70 @@ +Exercise +========= + ++ We want to develop a program that determines the future value of an investment, given the initial value and the interest rate ++ We follow the steps for development. + + ++ Analysis: + + The initial money generates an annual interest rate + + How much will it be worth in 10 years? + + Input: initial amount, interest rate + + Output: value in 10 years + ++ Specification: + + The user enters the initial amount invested + + The user enters the annual interest rate + + Value of the financial mathematical formula * (1 + interest) + ++ Design: + + Enter the initial investment amount. + + Enter the interest rate. + + Repeat 10 times: + + initial value = initial value * (1 + interest rate) + + Print the updated value. + ++ Implementation: + + Test values: + + 1000 dollars investment and 3% annual interest rate + + 1000 dollars investment and 10% annual interest rate + +.. activecode:: ac_l40_10_en + :nocodelens: + :stdin: + + value = float(input("Initial amount invested: ")) + rate = float(input("Annual interest rate: ")) + for i in range(10): + value = value * (1 + rate / 100) + print("Value after 10 years: %5.2f" % value) + + +FAQs +-------------------- +.. mchoice:: feedback_l40_10_1_en + :random: + :answer_a: Helps us build the correct product without waste or redundancy + :feedback_a: It often makes sense to write the test first and then write as much code as necessary to allow the test to pass. + :answer_b: Makes the code run faster. + :feedback_b: This is incorrect because defining tests doesn't directly affect the speed of the code. + :answer_c: Allows the programmer to write less code. + :feedback_c: This is incorrect because writing tests actually requires writing more code. + :answer_d: Not necessary for good programming. + :feedback_d: This is incorrect because defining tests is an important aspect of good programming practices. + :correct: a + + Why is defining some tests before implementation a good programming practice? + +.. mchoice:: feedback_l40_10_2_en + :random: + :answer_a: Allows testing of the program's logical flow before coding it. + :feedback_a: Writing pseudocode in the design stage provides several benefits, including the ability to test the logic and structure of the program before writing any actual code. + :answer_b: Saves time and effort in later coding. + :feedback_b: This is incorrect because writing pseudocode requires time and effort, but it's an investment that's worth it in the design stage. + :answer_c: Helps identify syntax errors in the code. + :feedback_c: This helps identify logical errors, gaps, and loopholes in the program design, which saves time and effort in the long run. + :answer_d: Facilitates code debugging. + :feedback_d: This helps identify logical errors, gaps, and loopholes in the program design, which saves time and effort in the long run. + :correct: a + + What is the advantage of writing pseudocode in the design stage? \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_11.rst.txt b/293/_sources/lectures/TWP40/TWP40_11.rst.txt new file mode 100644 index 0000000000..721d5eb2b4 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_11.rst.txt @@ -0,0 +1,53 @@ +Números básicos +=============== + ++ Existen dos tipos de datos numéricos: ``int`` y ``float``. ++ ¿Por qué existen diferentes tipos? + + Hay diferentes datos: los contadores son números enteros y el número PI no es. + + Las operaciones con números enteros son mucho más rápidas. + + Los números de coma flotante son aproximaciones: su precisión tiene un límite. + +.. codelens:: cl_l40_11a + + print(type(3)) + print(type(3.14)) + print(type(3.0)) + x = -32 + print(type(x)) + x = 32.0 + print(type(x)) + print(type(int(x))) + + +Tabla de operadores +------------------- + + +.. table:: **Tabla de operadores** + :widths: auto + + ======== ===================== + Operador Operación + ======== ===================== + \* Multiplicación + / División + \*\* Exponenciación + abs() Valor absoluto + % Resto de la división + // División entera + \- Resta + \+ Suma + ======== ===================== + +Operadores Numéricos +-------------------- + +.. codelens:: cl_l40_11b + + print(3 + 4) + print(3.0 + 4.0) + print(3.0 * 4.0) + print(4 ** 3) + print(4.0 ** 3) + print(abs(5)) + print(abs(-5)) diff --git a/293/_sources/lectures/TWP40/TWP40_11_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_11_en.rst.txt new file mode 100644 index 0000000000..d1659d8eba --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_11_en.rst.txt @@ -0,0 +1,52 @@ +Basic Numbers +============== + ++ There are two types of numeric data: ``int`` and ``float``. ++ Why are there different types? + + There are different kinds of data: counters are integers and PI is not. + + Operations with integers are much faster. + + Floating-point numbers are approximations: their precision has a limit. + +.. codelens:: cl_l40_11a_en + + print(type(3)) + print(type(3.14)) + print(type(3.0)) + x = -32 + print(type(x)) + x = 32.0 + print(type(x)) + print(type(int(x))) + + +Operator Table +-------------- + +.. table:: **Operator Table** + :widths: auto + + ======== ===================== + Operator Operation + ======== ===================== + \* Multiplication + / Division + \*\* Exponentiation + abs() Absolute Value + % Modulus + // Integer Division + \- Subtraction + \+ Addition + ======== ===================== + +Numeric Operators +----------------- + +.. codelens:: cl_l40_11b_en + + print(3 + 4) + print(3.0 + 4.0) + print(3.0 * 4.0) + print(4 ** 3) + print(4.0 ** 3) + print(abs(5)) + print(abs(-5)) \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_12.rst.txt b/293/_sources/lectures/TWP40/TWP40_12.rst.txt new file mode 100644 index 0000000000..a1dd11bd3b --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_12.rst.txt @@ -0,0 +1,22 @@ +División entera en lenguajes de programación antiguos +===================================================== + ++ Los lenguaje más antiguos generan un resultado completo en la división de enteros. ++ ``10/3`` será igual a 3 ++ Al calcular Fahrenheit a Celsius, tendré que modificarlo un poco mi programa si uso C o Java. + + +Conversión de grados usando C +----------------------------- + +.. code-block:: c + + #include + + int main(void){ + float F, C; + printf("Farenheit: "); + scanf("%f", &F); + C = 5.0 * (F - 32.0) / 9.0; + printf("Celsius: %2.1f\n", C); + } diff --git a/293/_sources/lectures/TWP40/TWP40_12_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_12_en.rst.txt new file mode 100644 index 0000000000..9492980de5 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_12_en.rst.txt @@ -0,0 +1,22 @@ +Integer division in old programming languages +===================================================== + ++ Oldest programming languages produce a complete result in integer division. ++ ``10/3`` equals 3 ++ When calculating Fahrenheit to Celsius, I will need to modify my program a bit if I use C or Java. + + +Converting degrees using C +--------------------------- + +.. code-block:: c + + #include + + int main(void){ + float F, C; + printf("Fahrenheit: "); + scanf("%f", &F); + C = 5.0 * (F - 32.0) / 9.0; + printf("Celsius: %2.1f\n", C); + } \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_1_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_1_en.rst.txt new file mode 100644 index 0000000000..5290c165d8 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_1_en.rst.txt @@ -0,0 +1,55 @@ +The Software Development Process +================================ + ++ Running programs created by others is relatively simple ++ The hard part is starting to create your own programs ++ Computers are very strict and there are many details ++ So it is necessary to be very systematic + +Steps in the Software Development Process +------------------------------------------ + ++ Analyze the problem: + + Understand exactly what is the problem to solve? + + Well-defined problem, halfway solved problem. + ++ Specification of what the program will do: + + Describe exactly what your program will do. + + At this stage, I shouldn't worry about how I'm going to make my program? but more decide exactly what it will do? + + What are the inputs and outputs of the program? + ++ Design the program: + + Formulate the general structure of the program. + + We can use pseudocode at this step. + ++ Implement the program: + + Design some tests to validate your program. + + Translate the project to any programming language. + + In this course we will use Python. + +Example: Fahrenheit to Celsius temperature converter +---------------------------------------------------- + ++ Problem analysis: + + Given a temperature in *Fahrenheit*, obtain the conversion in Celsius. + ++ Specification of what the program will do: + + Input: temperature in Fahrenheit + + Output: temperature in degrees Celsius + + Output: 5 * (F-32) / 9 + ++ Design of how the program will work: + + Read the value of temperature in Fahrenheit. + + Convert the value using the formula ``5 * (F-32) / 9`` + + Print the converted value. + ++ Implementation of the problem: + + Tests: 32F = 0C and 100F = 37.8C + +.. activecode:: ac_l40_1_en + :nocodelens: + :stdin: + + F = float(input("Fahrenheit: ")) + C = 5 * (F - 32) / 9 + print("Celsius: %2.1f" % C) \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_2.rst.txt b/293/_sources/lectures/TWP40/TWP40_2.rst.txt new file mode 100644 index 0000000000..602d9ceb11 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_2.rst.txt @@ -0,0 +1,21 @@ +Variables +========= + ++ Las variables son referencias a regiones de memoria que definiste para usarla en el programa. ++ Las variables ``F`` y ``C`` del ejemplo anterior son referencias a regiones de memoria. ++ Las variables ``F`` y ``f`` son diferentes, al igual que ``C`` y ``c``. ++ ``"F"`` o ``"C"`` no son variables. + +Variables con valores definidos e indefinidos +--------------------------------------------- + ++ Solo se puede usar el contenido de una variable si ya tiene un valor *definido* antes. ++ Si se usa variable que no tiene valor definido o se encuentra *indefinido* daría como resultado un error como el siguiente. + +.. activecode:: ac_l40_2 + :nocodelens: + :stdin: + + x = 42 + print(x) + print(y) diff --git a/293/_sources/lectures/TWP40/TWP40_2_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_2_en.rst.txt new file mode 100644 index 0000000000..0ac8dfb4f3 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_2_en.rst.txt @@ -0,0 +1,21 @@ +Variables +========= + ++ Variables are references to memory regions that you define to use in the program. ++ The variables ``F`` and ``C`` from the previous example are references to memory regions. ++ The variables ``F`` and ``f`` are different, just as ``C`` and ``c`` are. ++ ``"F"`` or ``"C"`` are not variables. + +Variables with defined and undefined values +--------------------------------------------- + ++ You can only use the content of a variable if it already has a *defined* value. ++ If you use a variable that has no defined value or is *undefined*, it would result in an error like the following. + +.. activecode:: ac_l40_2_en + :nocodelens: + :stdin: + + x = 42 + print(x) + print(y) \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_3.rst.txt b/293/_sources/lectures/TWP40/TWP40_3.rst.txt new file mode 100644 index 0000000000..ecde77c442 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_3.rst.txt @@ -0,0 +1,18 @@ +Palabras reservadas +=================== + ++ Existen palabras reservadas en Python. ++ Estas palabras no se pueden usar para declarar una variable, ni una función. ++ En el ejercicio de la conversión las palabras ``float``, ``input`` y ``print`` son palabras reservadas. + +.. activecode:: ac_l40_3 + :nocodelens: + + Este programa le permite ver la lista completa de todas las palabras reservadas que existen en Python. + Ejecute el programa para verlas. + ~~~~ + import keyword + print(keyword.kwlist) + ++ Aqui no se incluyen las funciones como ``float()``, ``input()``, ``int()``, pero estas también son palabras que cumplen con la restricción. ++ Podemos ver directivas como ``if``, ``else``, ``elif``, que ya hemos usando anteriormente. diff --git a/293/_sources/lectures/TWP40/TWP40_3_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_3_en.rst.txt new file mode 100644 index 0000000000..7df6fdd972 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_3_en.rst.txt @@ -0,0 +1,18 @@ +Reserved Words +============== + ++ There are reserved words in Python. ++ These words cannot be used to declare a variable or function. ++ In the conversion exercise, the words ``float``, ``input``, and ``print`` are reserved words. + +.. activecode:: ac_l40_3_en + :nocodelens: + + This program allows you to see a complete list of all reserved words in Python. + Execute the program to see them. + ~~~~ + import keyword + print(keyword.kwlist) + ++ Functions like ``float()``, ``input()``, and ``int()`` are not included here, but they are also words that meet the restriction. ++ We can see directives like ``if``, ``else``, and ``elif``, which we have used before. \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_4.rst.txt b/293/_sources/lectures/TWP40/TWP40_4.rst.txt new file mode 100644 index 0000000000..931ee3a58e --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_4.rst.txt @@ -0,0 +1,24 @@ +Literales o constantes +====================== + ++ Existen varios tipos de datos. ++ Los más simples son los llamados literales o constantes. + +.. code-block:: python + + """ + Fahrenheit, 5, 32 y 9 son valores literales o constantes. + """ + F = float(input("Fahrenheit: ")) + C = 5 * (F - 32) / 9 + print("Celsius: %2.1f" % C) + ++ ¡Recuerde que hay diferentes tipos de datos! por ejemplo: ``"32"`` no es lo mismo que ``32``. + +.. codelens:: cl_l40_4 + + print(int("32") == 32) + print("32" == str(32)) + print(32 == "32") + ++ Para comparar diferentes tipos, primero realice una conversión. diff --git a/293/_sources/lectures/TWP40/TWP40_4_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_4_en.rst.txt new file mode 100644 index 0000000000..cfde30ef9b --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_4_en.rst.txt @@ -0,0 +1,24 @@ +Literals or Constants +====================== + ++ There are several types of data. ++ The simplest ones are called literals or constants. + +.. code-block:: python + + """ + Fahrenheit, 5, 32 and 9 are literal or constant values. + """ + F = float(input("Fahrenheit: ")) + C = 5 * (F - 32) / 9 + print("Celsius: %2.1f" % C) + ++ Remember that there are different types of data! for example: ``"32"`` is not the same as ``32``. + +.. codelens:: cl_l40_4_en + + print(int("32") == 32) + print("32" == str(32)) + print(32 == "32") + ++ To compare different types, first perform a conversion. \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_5.rst.txt b/293/_sources/lectures/TWP40/TWP40_5.rst.txt new file mode 100644 index 0000000000..329dafde63 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_5.rst.txt @@ -0,0 +1,18 @@ +Comandos de salida +================== + ++ El comando o instrucción ``print`` sirve para mostrar información al usuario. + +Carácter de fin de línea +------------------------ + ++ El comando ``print`` agrega un salto de línea como carácter por defecto. ++ Se puede reemplazar el carácter de fin de línea utilizando ``end`` en el comando ``print``. + +.. codelens:: cl_l40_5 + + for x in "aguacate": + if x in "ae": + print(x, end=" ") + else: + print("*", end=" ") diff --git a/293/_sources/lectures/TWP40/TWP40_5_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_5_en.rst.txt new file mode 100644 index 0000000000..95fe65fd25 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_5_en.rst.txt @@ -0,0 +1,18 @@ +Exit Commands +================== + ++ The command or instruction ``print`` serves to display information to the user. + +End-of-line character +------------------------ + ++ The ``print`` command adds a line break as a character by default. ++ The end-of-line character can be replaced using ``end`` in the ``print`` command. + +.. codelens:: cl_l40_5_en + + for x in "avocado": + if x in "ae": + print(x, end=" ") + else: + print("*", end=" ") \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_6.rst.txt b/293/_sources/lectures/TWP40/TWP40_6.rst.txt new file mode 100644 index 0000000000..080e83db30 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_6.rst.txt @@ -0,0 +1,27 @@ +Asignación de variables +======================== + ++ Asignar una variable por lo general sigue el siguiente formato ```` = ```` ++ La ```` es calculada en el procesador y modifica el valor en la memoria referenciada por ````. + +.. codelens:: cl_l40_6a + + x = 5 + celsius = 5 + fahrenheit = 9 / 5 * celsius + 32 + + ++ Puede asignar valores a una misma variable varias veces. + +.. codelens:: cl_l40_6b + + x = 0 + print(x) + x = "aguacate" + print(x) + x = 3.14 + print(x) + x = x * 2 + print(x) + ++ En el ejemplo anterior, ``x`` toma el último valor asignado. diff --git a/293/_sources/lectures/TWP40/TWP40_6_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_6_en.rst.txt new file mode 100644 index 0000000000..9e2b1ca7e0 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_6_en.rst.txt @@ -0,0 +1,27 @@ +Variable Assignment +=================== + ++ Assigning a variable is usually done in the following format ```` = ```` ++ The ```` is calculated by the processor and modifies the value in the memory referenced by ````. + +.. codelens:: cl_l40_6a_en + + x = 5 + celsius = 5 + fahrenheit = 9 / 5 * celsius + 32 + + ++ You can assign values to the same variable several times. + +.. codelens:: cl_l40_6b_en + + x = 0 + print(x) + x = "avocado" + print(x) + x = 3.14 + print(x) + x = x * 2 + print(x) + ++ In the previous example, ``x`` takes the last assigned value. \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_7.rst.txt b/293/_sources/lectures/TWP40/TWP40_7.rst.txt new file mode 100644 index 0000000000..baf7bf2b27 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_7.rst.txt @@ -0,0 +1,15 @@ +Lectura y tarea +=============== + +.. activecode:: ac_l40_7 + :language: python3 + :python3_interpreter: brython + + string = input("Escribe un texto: ") + print(string) + n = int(input("Ingrese un número entero: ")) + print(n) + y = float(input("Ingrese un número en punto flotante: ")) + print(y) + x = eval(input("Ingrese una expresión matemática: ")) + print(x) diff --git a/293/_sources/lectures/TWP40/TWP40_7_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_7_en.rst.txt new file mode 100644 index 0000000000..afe88515e6 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_7_en.rst.txt @@ -0,0 +1,15 @@ +Reading and homework +==================== + +.. activecode:: ac_l40_7_en + :language: python3 + :python3_interpreter: brython + + string = input("Write a text: ") + print(string) + n = int(input("Enter an integer number: ")) + print(n) + y = float(input("Enter a float number: ")) + print(y) + x = eval(input("Enter a mathematical expression: ")) + print(x) \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_8.rst.txt b/293/_sources/lectures/TWP40/TWP40_8.rst.txt new file mode 100644 index 0000000000..8a9f803ab4 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_8.rst.txt @@ -0,0 +1,45 @@ +Asignación múltiple +=================== + + +.. activecode:: ac_l40_8 + :language: python3 + :python3_interpreter: brython + + n1, n2, n3, n4 = eval(input("Ingrese 4 notas separadas por comas: ")) + print("Media:", (n1 + n2 + n3 + n4) / 4) + x = 4 + y = 5 + suma, diferencia = x + y, x - y + print(suma) + print(diferencia) + x, y = y, x + print(x, y) + + ++ ¡Para intercambiar variables, la siguiente secuencia no funciona! + +.. codelens:: cl_l40_8a + + x = 4 + y = 5 + x = y + y = x + ++ Una solución sería usar una variable ``temporal``. + +.. codelens:: cl_l40_8b + + x = 4 + y = 5 + temporal = x + x = y + y = temporal + ++ También se puede utilizar la asignación múltiple que es más elegante. + +.. codelens:: cl_l40_8c + + x = 4 + y = 5 + x, y = y, x diff --git a/293/_sources/lectures/TWP40/TWP40_8_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_8_en.rst.txt new file mode 100644 index 0000000000..763e1eb3f8 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_8_en.rst.txt @@ -0,0 +1,45 @@ +Multiple assignment +=================== + + +.. activecode:: ac_l40_8_en + :language: python3 + :python3_interpreter: brython + + n1, n2, n3, n4 = eval(input("Enter 4 grades separated by commas: ")) + print("Mean:", (n1 + n2 + n3 + n4) / 4) + x = 4 + y = 5 + suma, difference = x + y, x - y + print(suma) + print(difference) + x, y = y, x + print(x, y) + + ++ To swap variables, the following sequence does not work! + +.. codelens:: cl_l40_8a_en + + x = 4 + y = 5 + x = y + y = x + ++ One solution would be to use a ``temp`` variable. + +.. codelens:: cl_l40_8b_en + + x = 4 + y = 5 + temp = x + x = y + y = temp + ++ Multiple assignment can also be used, which is more elegant. + +.. codelens:: cl_l40_8c_en + + x = 4 + y = 5 + x, y = y, x \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/TWP40_9.rst.txt b/293/_sources/lectures/TWP40/TWP40_9.rst.txt new file mode 100644 index 0000000000..a8ac44de89 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_9.rst.txt @@ -0,0 +1,20 @@ +Formas de iterar +================ ++ Existen diversas formas de iterar. ++ Todas siguen el siguiente patrón ``for in ``. + + +.. activecode:: ac_l40_9 + :nocodelens: + :stdin: + + print(list(range(10))) + + for k in range(10): + print(k, end=" ") + + for k in [0, 1, 2, 3]: + print(k, end=" ") + + for k in "aguacate": + print(k + k, end=" ") diff --git a/293/_sources/lectures/TWP40/TWP40_9_en.rst.txt b/293/_sources/lectures/TWP40/TWP40_9_en.rst.txt new file mode 100644 index 0000000000..a7761aabb4 --- /dev/null +++ b/293/_sources/lectures/TWP40/TWP40_9_en.rst.txt @@ -0,0 +1,21 @@ +Ways to iterate +=============== + ++ There are various ways to iterate. ++ All of them follow the pattern ``for in ``. + + +.. activecode:: ac_l40_9_en + :nocodelens: + :stdin: + + print(list(range(10))) + + for k in range(10): + print(k, end=" ") + + for k in [0, 1, 2, 3]: + print(k, end=" ") + + for k in "avocado": + print(k + k, end=" ") \ No newline at end of file diff --git a/293/_sources/lectures/TWP40/toctree.rst.txt b/293/_sources/lectures/TWP40/toctree.rst.txt new file mode 100644 index 0000000000..fab39cb795 --- /dev/null +++ b/293/_sources/lectures/TWP40/toctree.rst.txt @@ -0,0 +1,29 @@ +================== +Revisión general 3 +================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP40_1.rst + TWP40_2.rst + TWP40_3.rst + TWP40_4.rst + TWP40_5.rst + TWP40_6.rst + TWP40_7.rst + TWP40_8.rst + TWP40_9.rst + TWP40_10.rst + TWP40_11.rst + TWP40_12.rst diff --git a/293/_sources/lectures/TWP40/toctree_en.rst.txt b/293/_sources/lectures/TWP40/toctree_en.rst.txt new file mode 100644 index 0000000000..79e7cbd6c4 --- /dev/null +++ b/293/_sources/lectures/TWP40/toctree_en.rst.txt @@ -0,0 +1,29 @@ +================= +General review 3 +================= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP40_1_en.rst + TWP40_2_en.rst + TWP40_3_en.rst + TWP40_4_en.rst + TWP40_5_en.rst + TWP40_6_en.rst + TWP40_7_en.rst + TWP40_8_en.rst + TWP40_9_en.rst + TWP40_10_en.rst + TWP40_11_en.rst + TWP40_12_en.rst diff --git a/293/_sources/lectures/TWP42/TWP42_1.rst.txt b/293/_sources/lectures/TWP42/TWP42_1.rst.txt new file mode 100644 index 0000000000..5ac40482ec --- /dev/null +++ b/293/_sources/lectures/TWP42/TWP42_1.rst.txt @@ -0,0 +1,84 @@ +Usando SQL +========== + +Notas de surfistas +------------------ + ++ La Federación de Surf tiene los siguientes datos: número del surfista, + nombre, país, grado promedio, estilo, edad. ++ ¿Cómo usar estos datos? ++ Por ejemplo, quiero conocer a todos los surfistas mayores de 25 ++ ¡Usando una base de datos! En este caso, SQL. + +.. raw:: html + + + + + + ++ Previamente fue creada una base de datos con una tabla llamada ``surfers``. ++ Esta tabla tiene la información de los participantes del torneo de surf organizada en las siguientes columnas: ``id``, ``nombre``, ``pais``, ``media``, ``estilo``, ``edad``. ++ ``id`` es un número entero que identifica al concursante. ++ ``nombre`` es una string con su nombre y su apodo (si tiene uno). ++ ``pais`` muestra el país que está representando en el torneo. ++ ``media`` es el promedio de puntos obtenidos en el torneo. ++ ``estilo`` es el estilo que tiene su tabla de surf. ++ ``edad`` es un número entero que muestra la edad del concursante. + + +.. activecode:: ac_42_1 + :language: python3 + :python3_interpreter: brython + + En este ejercicio leeremos los datos de la tabla ``surfers`` y mostraremos + solo los mayores a 25 con una instrucción SQL (conocidas como query). + Actualmente, la consulta devuelve todos los datos en la tabla ``surfers``. + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + # el método de conexión de sqlite3 se ha importado para su uso + # uno puede hacer esto por la declaración + from sqlite3 import connect + + # inicie la conexión y conéctese a la tabla de surfers predefinida + base_datos = connect('surfers.db') + + + # crear un cursor y ejecutar la consulta + cursor = base_datos.cursor() + query = 'SELECT * FROM surfers' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if(linhas!=None): + for linha in linhas: + print("ID :",linha['id']) + print("Nombre :",linha['nombre']) + print("Pais :",linha['pais']) + print("Media :",linha['media']) + print("Estilo :",linha['estilo']) + print("Edad :",linha['edad']) + print() + + # cerrar el cursor + cursor.close() + + + + + diff --git a/293/_sources/lectures/TWP42/TWP42_1_en.rst.txt b/293/_sources/lectures/TWP42/TWP42_1_en.rst.txt new file mode 100644 index 0000000000..a3e313bf7f --- /dev/null +++ b/293/_sources/lectures/TWP42/TWP42_1_en.rst.txt @@ -0,0 +1,78 @@ +Using SQL +========= + +Surfer Notes +------------- + ++ The Surf Federation has the following data: surfer's number, name, country, average grade, style, age. ++ How to use this information? ++ For example, I want to know all surfers over 25. ++ Using a database! In this case, SQL. + +.. raw:: html + + + + + + ++ Previously, a database was created with a table called ``surfers``. ++ This table has the information of the surf tournament participants organized in the following columns: ``id``, ``name``, ``country``, ``average``, ``style``, ``age``. ++ ``id`` is an integer that identifies the contestant. ++ ``name`` is a string with his/her name and nickname (if any). ++ ``country`` shows the country he/she is representing in the tournament. ++ ``average`` is the average score obtained in the tournament. ++ ``style`` is the style of his/her surfboard. ++ ``age`` is an integer that shows the contestant's age. + + +.. activecode:: ac_42_1_en + :language: python3 + :python3_interpreter: brython + + In this exercise we will read the data from the table ``surfers`` and display + only those over 25 with an SQL statement (known as a query). + Currently, the query returns all the data in the ``surfers`` table. + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + # the connection method of sqlite3 has been imported for use + # one can do this by the statement + from sqlite3 import connect + + # initiate the connection and connect to the predefined surfers table + database = connect('surfers_en.db') + + + # create a cursor and execute the query + cursor = database.cursor() + query = 'SELECT * FROM surfers' + + cursor.execute(query) + # fetch the data + rows = cursor.fetchall() + # print the data + if(rows!=None): + for row in rows: + print("ID :",row['id']) + print("Name :",row['name']) + print("Country :",row['country']) + print("Average :",row['media']) + print("Style :",row['style']) + print("Age :",row['age']) + print() + + # close the cursor + cursor.close() \ No newline at end of file diff --git a/293/_sources/lectures/TWP42/TWP42_2.rst.txt b/293/_sources/lectures/TWP42/TWP42_2.rst.txt new file mode 100644 index 0000000000..9e967a2a2d --- /dev/null +++ b/293/_sources/lectures/TWP42/TWP42_2.rst.txt @@ -0,0 +1,109 @@ +Conceptos básicos de SQL +======================== + +.. raw:: html + + + + + +.. image:: ../img/TWP42_003.jpeg + :height: 12.571cm + :width: 10.861cm + :align: center + :alt: + + +Nociones de bases de datos +-------------------------- + + +.. image:: ../img/TWP42_004.jpeg + :height: 14.001cm + :width: 14.001cm + :align: center + :alt: + + +.. image:: ../img/TWP42_005.jpeg + :height: 13.953cm + :width: 17.401cm + :align: center + :alt: + + +Crear un base de estudiantes +---------------------------- + +.. activecode:: ac_42_2_1 + :language: python3 + :python3_interpreter: brython + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + # el siguiente código crea una tabla + # llamada alumnos en la base de datos alomnos.bd + from sqlite3 import connect + con = connect('alumnos.bd') + cur = con.cursor() + + # la tabla tiene dos columnas: login_id y pass + cur.execute('''create table alumnos(login_id varchar(8),pass integer)''') + cur.close() + con.close() + + +Accediendo a la base alumnos.bd +------------------------------- + +.. activecode:: ac_42_2_2 + :language: python3 + :python3_interpreter: brython + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + con = connect('alumnos.bd') + cur = con.cursor() + + # insertar valores en la tabla de alumnos + cur.execute('insert into alumnos values("masanori",421)') + cur.execute('insert into alumnos values("emengarda",666)') + + # selecciona todo el contenido de la tabla de alumnos + cur.execute('select * from alumnos') + + result = cur.fetchall() + + if(result!=None): + for res in result: + print("login :",res['login_id']) + print("ra :",res['pass']) + + cur.close() + con.close() + + + + + diff --git a/293/_sources/lectures/TWP42/TWP42_2_en.rst.txt b/293/_sources/lectures/TWP42/TWP42_2_en.rst.txt new file mode 100644 index 0000000000..d1b64e2225 --- /dev/null +++ b/293/_sources/lectures/TWP42/TWP42_2_en.rst.txt @@ -0,0 +1,104 @@ +Basic concepts of SQL +======================== + +.. raw:: html + + + + + +.. image:: ../img/TWP42_003.jpeg + :height: 12.571cm + :width: 10.861cm + :align: center + :alt: + + +Notions of databases +-------------------------- + + +.. image:: ../img/TWP42_004.jpeg + :height: 14.001cm + :width: 14.001cm + :align: center + :alt: + + +.. image:: ../img/TWP42_005.jpeg + :height: 13.953cm + :width: 17.401cm + :align: center + :alt: + + +Creating a student database +---------------------------- + +.. activecode :: ac_42_2_1_en + :language: python3 + :python3_interpreter: brython + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + # the following code creates a table + # called students in the database students.bd + from sqlite3 import connect + con = connect('students.bd') + cur = con.cursor() + + # the table has two columns: login_id and pass + cur.execute('''create table students(login_id varchar(8),pass integer)''') + cur.close() + con.close() + + +Accessing the students.bd database +---------------------------------- + +.. activecode :: ac_42_2_2_en + :language: python3 + :python3_interpreter: brython + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + con = connect('students.bd') + cur = con.cursor() + + # insert values into the students table + cur.execute('insert into students values("masanori",421)') + cur.execute('insert into students values("emengarda",666)') + + # select all the contents of the students table + cur.execute('select * from students') + + result = cur.fetchall() + + if(result!=None): + for res in result: + print("login :",res['login_id']) + print("ra :",res['pass']) + + cur.close() + con.close() \ No newline at end of file diff --git a/293/_sources/lectures/TWP42/TWP42_3.rst.txt b/293/_sources/lectures/TWP42/TWP42_3.rst.txt new file mode 100644 index 0000000000..b9a0749a1a --- /dev/null +++ b/293/_sources/lectures/TWP42/TWP42_3.rst.txt @@ -0,0 +1,340 @@ +Más conceptos de SQL +==================== + + +.. raw:: html + + + + + +Esquema de base de datos chinook +-------------------------------- + ++ The Chinook data model represents a digital media store, including tables for artists, albums, media tracks, invoices, and customers. + +.. image:: ../img/TWP42_009.png + :height: 20.0cm + :width: 15.0cm + :align: center + :alt: + +Seleccionando diferentes tablas de las bases de datos +----------------------------------------------------- +.. activecode:: ac_42_3a + :language: python3 + :python3_interpreter: brython + + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + # elegir una columna en particular de una tabla + # limitar los resultados a las primeras 30 filas + query = 'select * from Track limit 30;' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() + + + +Ordenar filas +------------- +.. activecode:: ac_42_3b + :language: python3 + :python3_interpreter: brython + + La cláusula ``ORDER BY`` se utiliza para ordenar un conjunto de resultados de una consulta. SQLite almacena datos en las tablas en + un orden no especificado. Significa que las filas de la tabla pueden o no estar en el orden en que fueron insertadas. Si usa la + declaración ``SELECT`` para consultar datos de una tabla, el orden de las filas en el conjunto de resultados no se especifica. Para + ordenar el conjunto de resultados, agregue la cláusula ``ORDER BY`` a la declaración ``SELECT`` de la siguiente manera: + + ``ORDER BY column_name [ASC | DESC]`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + # ordenar las filas según la columna de miliseconds + query = '''select name, milliseconds, albumid from Track + ORDER BY milliseconds ASC limit 30;''' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() + + + +Filtrado de datos +----------------- + ++ Ya hemos visto algunas formas de archivar datos, por ej. Cláusula LIMIT. ++ En la siguiente sección, veremos algunas formas más de filtrar datos, específicamente las cláusulas WHERE, IN, BETWEEN y LIKE. + +.. activecode:: ac_42_3c1 + :language: python3 + :python3_interpreter: brython + + En este bloque aprenderemos a usar la cláusula ``WHERE``. La cláusula ``WHERE`` es una cláusula opcional de la instrucción SELECT. + Aparece después de la cláusula ``FROM`` como la siguiente declaración: + + ``WHERE column_name [= | != | < | <= | > | >=] value`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + query = '''select name, milliseconds, bytes, albumid + from Track WHERE albumid=1 limit 30;''' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() + + +.. activecode:: ac_42_3c2 + :language: python3 + :python3_interpreter: brython + + En este bloque aprenderemos a usar la cláusula ``BETWEEN``. El operador ``BETWEEN`` es un operador lógico que comprueba + si un valor está dentro del rango de valores. Si el valor está en el rango especificado, el operador ``BETWEEN`` devuelve + verdadero. El operador ``BETWEEN`` se puede utilizar en la cláusula ``WHERE`` de las instrucciones ``SELECT``, ``DELETE``, ``UPDATE`` y ``REPLACE``. + La siguiente declaración muestra un ejemplo de la cláusula ``BETWEEN``: + + ``BETWEEN value1 AND value2`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + query = '''select InvoiceId, BillingAddress,Total from + Invoice WHERE Total BETWEEN 14.91 and 18.86 ORDER BY Total;''' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() + + +.. activecode:: ac_42_3c3 + :language: python3 + :python3_interpreter: brython + + En este bloque, aprenderemos a usar el operador IN de SQLite para determinar si un valor coincide con algún valor en una lista + de valores o con el resultado de una subconsulta. El operador SQLite IN determina si un valor coincide con cualquier valor en una + lista o una subconsulta. La sintaxis del operador IN es la siguiente: + + ``IN (value1, value2, ..., valueN)`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + query = '''select TrackId, Name, AlbumId from Track + WHERE AlbumId IN (16, 17, 18) ORDER BY AlbumId;''' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() + +.. activecode:: ac_42_3c4 + :language: python3 + :python3_interpreter: brython + + En esta parte aprenderemos sobre la cláusula LIKE. La cláusula LIKE es un operador de búsqueda que permite buscar una cadena de caracteres + dentro de una cadena de caracteres. La sintaxis de la cláusula LIKE es la siguiente: + + ``LIKE '%value%'`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + query = '''select TrackId, Name from Track WHERE name LIKE 'Wild%';''' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() + + +Agrupación de datos +------------------- + +.. activecode:: ac_42_4a + :language: python3 + :python3_interpreter: brython + + En esta sección, aprenderemos a usar la cláusula ``GROUP BY`` de SQLite para crear un conjunto de filas de resumen a partir de un conjunto de filas. + La cláusula ``GROUP BY`` es una cláusula opcional de la instrucción ``SELECT``. La cláusula ``GROUP BY`` un grupo seleccionado de filas en filas de resumen + por valores de una o más columnas. La cláusula ``GROUP BY`` devuelve una fila para cada grupo. Para cada grupo, puede aplicar una función agregada como + ``MIN``, ``MAX``, ``SUM``, ``COUNT`` o ``AVG`` para proporcionar más información sobre cada grupo. La siguiente declaración ilustra la sintaxis de la cláusula + ``GROUP BY`` de SQLite: + + ``GROUP BY column1, column2, ...`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + query = 'select albumid, COUNT(trackid) FROM Track GROUP BY albumid;' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() + + +.. activecode:: ac_42_4b + :language: python3 + :python3_interpreter: brython + + Aquí aprenderemos a usar la cláusula ``HAVING`` de SQLite para especificar una condición de filtro para un grupo o un agregado. + La cláusula SQLite ``HAVING`` es una cláusula opcional de la declaración ``SELECT``. La cláusula ``HAVING`` especifica una condición de + búsqueda para un grupo. A menudo usamos la cláusula ``HAVING`` con la cláusula ``GROUP BY``. La cláusula ``GROUP BY`` agrupa un conjunto + de filas en un conjunto de filas o grupos de resumen. Luego, la cláusula ``HAVING`` filtra grupos en función de una condición + específica. Si usamos la cláusula HAVING, debemos incluir la cláusula ``GROUP BY``; de lo contrario, se producirá un error. + + A continuación se ilustra la sintaxis de la cláusula ``HAVING``: + + ``HAVING condition`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # conectarse a la base de datos chinook + base_datos = connect('Chinook_Sqlite.sqlite') + cursor = base_datos.cursor() + + query = '''select albumid, COUNT(trackid) FROM Track GROUP BY albumid + HAVING COUNT(albumid) BETWEEN 18 AND 20;''' + + cursor.execute(query) + # obtener los datos + linhas = cursor.fetchall() + # imprimir los datos + if linhas: + for i in range(len(linhas)): + for k in linhas[i].keys(): + print(k,":",linhas[i][k]) + print() + + # cerrar el cursor + cursor.close() \ No newline at end of file diff --git a/293/_sources/lectures/TWP42/TWP42_3_en.rst.txt b/293/_sources/lectures/TWP42/TWP42_3_en.rst.txt new file mode 100644 index 0000000000..864aacf44b --- /dev/null +++ b/293/_sources/lectures/TWP42/TWP42_3_en.rst.txt @@ -0,0 +1,337 @@ +More SQL Concepts +================== + + +.. raw:: html + + + + + +Chinook Database schema +------------------------ + ++ The Chinook data model represents a digital media store, including tables for artists, albums, media tracks, invoices, and customers. + +.. image:: ../img/TWP42_009.png + :height: 20.0cm + :width: 15.0cm + :align: center + :alt: + +Selecting different tables from the databases +----------------------------------------------- +.. activecode:: ac_42_3a_en + :language: python3 + :python3_interpreter: brython + + + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # connect to the Chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + # choose a particular column from a table + # limit the results to the first 30 rows + query = 'select * from Track limit 30;' + + cursor.execute(query) + # get the data + rows = cursor.fetchall() + # print the data + if rows: + for i in range(len(rows)): + for k in rows[i].keys(): + print(k,":",rows[i][k]) + print() + + # close the cursor + cursor.close() + + + +Sorting rows +------------- +.. activecode:: ac_42_3b_en + :language: python3 + :python3_interpreter: brython + + The ``ORDER BY`` clause is used to sort a set of results from a query. SQLite stores data in tables in + an unspecified order. It means that table rows may or may not be in the order they were inserted into the table. If you use the + ``SELECT`` statement to query data from a table, the order of the rows in the result set is unspecified. To sort the result set, add + the ``ORDER BY`` clause to the ``SELECT`` statement like this: + + ``ORDER BY column_name [ASC | DESC]`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # connect to the Chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + # sort the rows according to the miliseconds column + query = '''select name, milliseconds, albumid from Track + ORDER BY milliseconds ASC limit 30;''' + + cursor.execute(query) + # get the data + rows = cursor.fetchall() + # print the data + if rows: + for i in range(len(rows)): + for k in rows[i].keys(): + print(k,":",rows[i][k]) + print() + + # close the cursor + cursor.close() + + + +Data filtering +-------------- + ++ We have already seen some ways of archiving data, e.g., the `LIMIT` clause. ++ In the following section, we will see some more ways to filter data, specifically the `WHERE`, `IN`, `BETWEEN`, and `LIKE` clauses. + +.. activecode:: ac_42_3c1_en + :language: python3 + :python3_interpreter: brython + + This block teaches us how to use the `WHERE` clause. The `WHERE` clause is an optional clause of the `SELECT` statement. + It appears after the `FROM` clause as the following statement: + + ``WHERE column_name [= | != | < | <= | > | >=] value`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # connect to the Chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + query = '''select name, milliseconds, bytes, albumid + from Track WHERE albumid=1 limit 30;''' + + cursor.execute(query) + # get the data + rows = cursor.fetchall() + # print the data + if rows: + for i in range(len(rows)): + for k in rows[i].keys(): + print(k,":",rows[i][k]) + print() + + # close the cursor + cursor.close() + + +.. activecode:: ac_42_3c2_en + :language: python3 + :python3_interpreter: brython + + In this block, we will learn how to use the ``BETWEEN`` clause. The ``BETWEEN`` operator is a logical operator that checks + whether a value is within a range of values. If the value is in the specified range, the ``BETWEEN`` operator returns true. The + ``BETWEEN`` operator can be used in the ``WHERE`` clause of ``SELECT``, ``DELETE``, ``UPDATE``, and ``REPLACE`` statements. The + following statement shows an example of the ``BETWEEN`` clause: + + ``BETWEEN value1 AND value2`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # Connect to Chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + query = '''select InvoiceId, BillingAddress, Total from + Invoice WHERE Total BETWEEN 14.91 and 18.86 ORDER BY Total;''' + + cursor.execute(query) + # Get the data + rows = cursor.fetchall() + # Print the data + if rows: + for i in range(len(rows)): + for k in rows[i].keys(): + print(k, ":", rows[i][k]) + print() + + # Close the cursor + cursor.close() + + +.. activecode:: ac_42_3c3_en + :language: python3 + :python3_interpreter: brython + + In this block, we will learn how to use the SQLite IN operator to determine whether a value matches any value in a list + of values or the result of a subquery. The SQLite IN operator determines whether a value matches any value in a + list or a subquery result. The syntax of the IN operator is as follows: + + ``IN (value1, value2, ..., valueN)`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # Connect to Chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + query = '''select TrackId, Name, AlbumId from Track + WHERE AlbumId IN (16, 17, 18) ORDER BY AlbumId;''' + + cursor.execute(query) + # Get the data + rows = cursor.fetchall() + # Print the data + if rows: + for i in range(len(rows)): + for k in rows[i].keys(): + print(k, ":", rows[i][k]) + print() + + # Close the cursor + cursor.close() + +.. activecode:: ac_42_3c4_en + :language: python3 + :python3_interpreter: brython + + In this section, we will learn about the LIKE clause. The LIKE clause is a search operator that allows you to search for a character string + within another character string. The syntax of the LIKE clause is as follows: + + ``LIKE '%value%'`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # Connect to Chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + query = '''select TrackId, Name from Track WHERE name LIKE 'Wild%';''' + + cursor.execute(query) + # Get the data + rows = cursor.fetchall() + # Print the data + if rows: + for i in range(len(rows)): + for k in rows[i].keys(): + print(k, ":", rows[i][k]) + print() + + # Close the cursor + cursor.close() + +Grouping of data +---------------- + +.. activecode:: ac_42_4a_en + :language: python3 + :python3_interpreter: brython + + In this section, we will learn how to use the ``GROUP BY`` clause of SQLite to create a summary row set from a row set. + The ``GROUP BY`` clause is an optional clause of the ``SELECT`` statement. The ``GROUP BY`` clause groups a selected set of rows into summary rows + by values of one or more columns. The ``GROUP BY`` clause returns one row for each group. For each group, you can apply an aggregate function such as + ``MIN``, ``MAX``, ``SUM``, ``COUNT``, or ``AVG`` to provide more information about each group. The following statement illustrates the syntax of the ``GROUP BY`` clause of SQLite: + + ``GROUP BY column1, column2, ...`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # connect to the chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + query = 'select albumid, COUNT(trackid) FROM Track GROUP BY albumid;' + + cursor.execute(query) + # get the data + lines = cursor.fetchall() + # print the data + if lines: + for i in range(len(lines)): + for k in lines[i].keys(): + print(k,":",lines[i][k]) + print() + + # close the cursor + cursor.close() + + +.. activecode:: ac_42_4b_en + :language: python3 + :python3_interpreter: brython + + Here we will learn how to use the SQLite ``HAVING`` clause to specify a filter condition for a group or aggregate. + The SQLite ``HAVING`` clause is an optional clause of the ``SELECT`` statement. The ``HAVING`` clause specifies a search condition for a group. + We often use the ``HAVING`` clause with the ``GROUP BY`` clause. The ``GROUP BY`` clause groups a set of rows into a set of summary rows or groups. + Then, the ``HAVING`` clause filters groups based on a specific condition. If we use the HAVING clause, we must include the ``GROUP BY`` clause; otherwise, an error will occur. + + The following illustrates the syntax of the ``HAVING`` clause: + + ``HAVING condition`` + ~~~~ + import sys + sys.path.append("../../_static") + + ^^^^ + from sqlite3 import connect + + # connect to the chinook database + database = connect('Chinook_Sqlite.sqlite') + cursor = database.cursor() + + query = '''select albumid, COUNT(trackid) FROM Track GROUP BY albumid + HAVING COUNT(albumid) BETWEEN 18 AND 20;''' + + cursor.execute(query) + # get the data + lines = cursor.fetchall() + # print the data + if lines: + for i in range(len(lines)): + for k in lines[i].keys(): + print(k,":",lines[i][k]) + print() + + # close the cursor + cursor.close() \ No newline at end of file diff --git a/293/_sources/lectures/TWP42/toctree.rst.txt b/293/_sources/lectures/TWP42/toctree.rst.txt new file mode 100644 index 0000000000..229fc154f4 --- /dev/null +++ b/293/_sources/lectures/TWP42/toctree.rst.txt @@ -0,0 +1,20 @@ +============== +Bases de datos +============== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP42_1.rst + TWP42_2.rst + TWP42_3.rst \ No newline at end of file diff --git a/293/_sources/lectures/TWP42/toctree_en.rst.txt b/293/_sources/lectures/TWP42/toctree_en.rst.txt new file mode 100644 index 0000000000..cb155f4567 --- /dev/null +++ b/293/_sources/lectures/TWP42/toctree_en.rst.txt @@ -0,0 +1,20 @@ +========= +Databases +========= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP42_1_en.rst + TWP42_2_en.rst + TWP42_3_en.rst diff --git a/293/_sources/lectures/TWP45/TWP45_1.rst.txt b/293/_sources/lectures/TWP45/TWP45_1.rst.txt new file mode 100644 index 0000000000..cd25d52d51 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_1.rst.txt @@ -0,0 +1,72 @@ +Facebook Hacking +================ + + +.. image:: ../img/TWP45_001.jpeg + :height: 10.225cm + :width: 14.801cm + :align: center + :alt: + + +¿Los hackers no son "malvados"? +------------------------------- + +Facebook está dirigido por hackers. La mayoría de la gente piensa en un hacker +como alguien que irrumpe en un sistema informático. Pero nosotros vemos esto +como una filosofía. Aquí, los hackers asumen que siempre hay una forma mejor +y más eficiente de resolver problemas ". facebook.com/careers (2012) + + +.. image:: ../img/TWP45_002.jpeg + :height: 11.747cm + :width: 17.638cm + :align: center + :alt: + + +Obtener foto de perfil de Facebook +---------------------------------- + +Para este ejercicio utilizaremos un intérprete de Python llamado Brython. +Éste incluye un módulo llamado browser que, a diferencia de los ejercicios +anteriores, nos permitirá mostrar una página con elementos HTML +(botones, cajas de texto, títulos, etc.), en lugar de solo mostrar impresiones +en consola. +En el siguiente enlace puedes encontrar una guía de todos los elementos HTML +que Brython soporta: https://brython.info/static_doc/en/html.html + +.. activecode:: ac_l45_1 + :language: python3 + :python3_interpreter: brython + + Este ejercicio obtiene la foto de perfil según el nombre de usuario de un perfil público de Facebook. + Pruébalo por tu propia cuenta! + + ~~~~ + from browser import document, html + + # Se crean dos secciones de divisiones con el elemento DIV. + # Y se separan por un salto de linea con el elemento BR. + document <= html.DIV(id="div_cajas_texto") + document <= html.BR() + document <= html.DIV(id='div_imagen') + + # El elemento H2 crea un título, INPUT crea la caja de texto y BUTTON crea un botón. + # Todos estos se ponen dentro de la división con id="div_cajas_texto" + document['div_cajas_texto'] <= html.H2("Ingrese un usuario de Facebook público") + document['div_cajas_texto'] <= html.INPUT(id="input_usuario", placeholder="ArianaGrande") + document['div_cajas_texto'] <= html.BUTTON("Mostrar foto",id="boton_mostrar") + + # Se crea la función que se le asignará al botón de mostrar foto. + def obtener_foto(evento): + # Se toma el texto que se escribe adentro de la caja con id="input_usuario" con .value + nombre_usuario = document["input_usuario"].value + # Se concatena el nombre de usuario con el enlace de la API de Facebook + link = 'https://graph.facebook.com/' + nombre_usuario + '/picture?type=large' + # Se agrega una imagen con fuente del link construido anteriormente mediante src + # dentro de la división de id='div_imagen' + document['div_imagen'] <= html.IMG(src=link, id="img_obtenida") + + # Por último se le ordena al botón de id="boton_mostrar" que ejecute la función obtener_foto. + document["boton_mostrar"].bind("click", obtener_foto) diff --git a/293/_sources/lectures/TWP45/TWP45_1_en.rst.txt b/293/_sources/lectures/TWP45/TWP45_1_en.rst.txt new file mode 100644 index 0000000000..23be042a55 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_1_en.rst.txt @@ -0,0 +1,64 @@ +Facebook Hacking +================ + + +.. image:: ../img/TWP45_001.jpeg + :height: 10.225cm + :width: 14.801cm + :align: center + :alt: + + +Are hackers not "evil"? +------------------------------- + +Facebook is run by hackers. Most people think of a hacker as someone who breaks into a computer system. But we see this as a philosophy. Here, hackers assume that there is always a better and more efficient way to solve problems. ". facebook.com/careers (2012) + + +.. image:: ../img/TWP45_002.jpeg + :height: 11.747cm + :width: 17.638cm + :align: center + :alt: + + +Get Facebook profile picture +---------------------------------- + +For this exercise we will use a Python interpreter called Brython. This includes a module called browser which, unlike previous exercises, will allow us to display a page with HTML elements (buttons, text boxes, titles, etc.), instead of just displaying prints in the console. +In the following link you can find a guide to all the HTML elements that Brython supports: https://brython.info/static_doc/en/html.html + +.. activecode:: ac_l45_1_en + :language: python3 + :python3_interpreter: brython + + This exercise retrieves the profile picture based on the username of a public Facebook profile. + Try it out for yourself! + + ~~~~ + from browser import document, html + + # Two division sections are created with the DIV element. + # And separated by a line break with the BR element. + document <= html.DIV(id="div_text_boxes") + document <= html.BR() + document <= html.DIV(id='div_image') + + # The H2 element creates a title, INPUT creates the text box and BUTTON creates a button. + # All of these are placed inside the division with id="div_text_boxes" + document['div_text_boxes'] <= html.H2("Enter a public Facebook user") + document['div_text_boxes'] <= html.INPUT(id="input_user", placeholder="ArianaGrande") + document['div_text_boxes'] <= html.BUTTON("Show photo",id="button_show") + + # The function that will be assigned to the show photo button is created. + def get_photo(event): + # The text that is written within the box with id="input_user" is taken with .value + username = document["input_user"].value + # The username is concatenated with the Facebook API link + link = 'https://graph.facebook.com/' + username + '/picture?type=large' + # An image with the source of the link constructed above is added using src + # within the division of id ='div_image' + document['div_image'] <= html.IMG(src=link, id="img_obtained") + + # Finally, the show photo button with id="button_show" is instructed to execute the function get_photo. + document["button_show"].bind("click", get_photo) \ No newline at end of file diff --git a/293/_sources/lectures/TWP45/TWP45_2.rst.txt b/293/_sources/lectures/TWP45/TWP45_2.rst.txt new file mode 100644 index 0000000000..f06701a342 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_2.rst.txt @@ -0,0 +1,36 @@ +Obtener datos de Reddit +======================= + +En este ejercicio vamos a acceder a Reddit para obetener datos como los de la siguiente imagen. + +.. image:: ../img/TWP45_050.png + :height: 9.39cm + :width: 23.344cm + :align: center + :alt: + +.. activecode:: ac_l45_2 + :nocodelens: + :language: python + + import urllib.request + import json + + # La url de Reddit a la que accederemos + url = "https://cors.bridged.cc/http://www.reddit.com/r/Python/.json" + resp = urllib.request.urlopen(url).read() + + # La respuesta se da en formato json, se debe transformar a + # un diccionario de Python con json.loads + texto = json.loads(resp) + + # Puede ver los datos que se recibieron si quita el comentario de abajo + # print(texto) + + # Buscamos e imprimimos los datos que queremos + for item in texto["data"]["children"]: + doc = item["data"] + print(doc["title"]) + print("#comments: %d" % doc["num_comments"]) + print(doc["url"]) + print() diff --git a/293/_sources/lectures/TWP45/TWP45_2_en.rst.txt b/293/_sources/lectures/TWP45/TWP45_2_en.rst.txt new file mode 100644 index 0000000000..ce13cce510 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_2_en.rst.txt @@ -0,0 +1,36 @@ +Get data from Reddit +======================= + +In this exercise we are going to access Reddit to obtain data like the one in the following image. + +.. image:: ../img/TWP45_050.png + :height: 9.39cm + :width: 23.344cm + :align: center + :alt: + +.. activecode:: ac_l45_2_en + :nocodelens: + :language: python + + import urllib.request + import json + + # The Reddit URL we'll access + url = "https://cors.bridged.cc/http://www.reddit.com/r/Python/.json" + resp = urllib.request.urlopen(url).read() + + # The response is in JSON format, it needs to be transformed + # into a Python dictionary with json.loads + text = json.loads(resp) + + # You can see the received data if you uncomment the line below + # print(text) + + # We search and print the data we want + for item in text["data"]["children"]: + doc = item["data"] + print(doc["title"]) + print("#comments: %d" % doc["num_comments"]) + print(doc["url"]) + print() \ No newline at end of file diff --git a/293/_sources/lectures/TWP45/TWP45_3.rst.txt b/293/_sources/lectures/TWP45/TWP45_3.rst.txt new file mode 100644 index 0000000000..24660a01d6 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_3.rst.txt @@ -0,0 +1,160 @@ +Probando la API de TasteDive +============================ + +TasteDive es una herramienta que: + + le ayuda a descubrir nueva música, películas, programas de televisión, libros, autores, juegos, + podcasts y personas con intereses compartidos. + -- TasteDive + +En el siguiente ejercicio usaremos la API de TasteDive para buscar obras o artistas similares a otra de nuestra +elección. +La documentación de la API de `TasteDive `_. + +.. activecode:: ac_l45_3a + :nocodelens: + :language: python + + En este caso, utilizaremos la librería ``requests`` para hacer la solicitud a la API. La url base + es ``"https://tastedive.com/api/similar"``. A esta url se le va a pasar un parámetro ``q`` con el + valor de la artista Ariana Grande. Al final la url se va a ver de la siguiente forma: ``"https://tastedive.com/api/similar?q=ariana+grande"``. + Note que después de la url base se escribe un ``?`` para indicar que siguen los parámetros. + + ~~~~ + import requests + import json + + api_url = "https://tastedive.com/api/similar" + proxy = "https://cors.bridged.cc/" + + # Los parámetros que se le pasaran a la url los escribimos dentro de un diccionario + parametros = {"q": "ariana grande"} + + # Solicitamos a la api los datos + respuesta = requests.get(proxy + api_url, params=parametros) + + # Ahora imprimimos la url + print(respuesta.url) + print() + + # Transformamos los datos de formato json a Python + datos = json.loads(respuesta.text) + + print(datos) + + +En el ejemplo anterior pudo apreciar que la API regresa un texto, que si lo pasamos por ``json.loads`` +se transforma a un diccionario de Python. Sin embargo, no es del todo legible. Esto se puede solucionar con +``json.dumps``. + +.. activecode:: ac_l45_3b + :language: python3 + :python3_interpreter: brython + + + Ahora vamos a solicitar información de la banda Coldplay. Esta vez vamos a imprimir los datos de forma + que sean legibles. Esto lo hacemos con el argumento ``indent`` de la función ``dumps`` de ``json``. + Vamos a usar ``urllib`` para hacer la solicitud. + + ~~~~ + import urllib.request + import urllib.parse + import json + + api_url = "https://tastedive.com/api/similar?" + proxy = "https://cors.bridged.cc/" + # La siguiente línea es para los parámetros de la url. + parametros = urllib.parse.urlencode({"q": "coldplay"}) + + solicitud = urllib.request.urlopen(proxy + api_url + parametros) + datos = json.loads(solicitud.read()) + + # Imprimimos los datos de forma legible para un usuario + print(json.dumps(datos, indent=4)) + + # Podemos ver que la api arrojó 20 resultados relacionados con + # la solicitud + print(len(datos["Similar"]["Results"])) + + +| + +El siguiente ejercicio viene con calificación automática. + +.. activecode:: ac_l45_3c + :nocodelens: + :language: python + + Ahora va a preguntar a TasteDive por la película Coco. Entonces el diccionario ``parametros`` debe tener el + valor ``"Coco"`` asignado a la llave ``"q"``. Además, esta vez solo queremos 5 resultados en vez de 20. Para + esto existe un parámetro llamado ``"limit"``, que puede ser asignado al número de resultados que se necesiten. + Otro parámetro que le pasará a la url será ``"info"`` y tendrá el valor de 1. Lo que hará esto es que los + resultados vendrán con un texto extra con información sobre la película. + + Primero, va a solicitar a la API lo descrito anteriormente, y guardará esto en la variable ``solicitud``. En + otra variable, ``solicitud_url``, guarde la url de la solicitud. Después asignará los datos a la variable ``datos``. + Después va asignar a la variable ``resultados`` el número de resultados que arrojó la solicitud + (como se hizo en el ejemplo anterior). Como pusimos un límite, este número debe coincidir con el límite. + + Ahora va a crear la lista ``peliculas_similares``. Dentro de ``datos`` usted tiene un diccionario de diccionarios + y listas. Lo que hará será buscar los conjuntos dentro de los cuales se encuentren los nombres de las películas + similares a Coco, y va a agregar a ``peliculas_similares`` el nombre de esas películas. En total deben ser 5. + **Pista**: los datos de las películas se encuentran dentro de ``datos["Similar"]["Results"]``, y la llave para + acceder a ellas es ``"Name"``. + + Por último, va a buscar el número de veces que aparece la palabra ``"Pixar"`` en los textos de información de las + películas relacionadas a Coco. Ese número lo va a guardar en la variable ``pixar``. **Pista**: ``"wTeaser"`` es la + llave que guarda el texto. Esta llave se encuentra en el mismo diccionario que el nombre de las películas. + + ~~~~ + import requests + import json + + api_url = "https://tastedive.com/api/similar" + proxy = "https://cors.bridged.cc/" + + # Agregue los parámetros + parametros = {} + + # Complete el código + solicitud = + solicitud_url = + datos = + + # Asigne la variable resultados + + # print(f"resultados: {resultados}") + + # Cree peliculas_similares + # Utilice un ciclo for para encontrar las peliculas similares y agregarlas + # a la variable correspondiente + + # print(f"Pelis: {peliculas_similares} len: {len(peliculas_similares)}") + + pixar = 0 + # Busque el número de ocurrencias de "Pixar" dentro de los datos + + # print(f"Pixar: {pixar}") + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual( + solicitud_url, + "https://cors.bridged.cc/https://tastedive.com/api/similar?q=Coco&limit=5&info=1", + "Probando que la url sea: https://cors.bridged.cc/https://tastedive.com/api/similar?q=Coco&limit=5&info=1", + ) + self.assertEqual(resultados, 5, "Probando que resultados esté asignado correctamente.") + self.assertEqual(len(peliculas_similares), 5, "Probando que peliculas_similares sean: 5") + self.assertEqual( + peliculas_similares, + ["Toy Story 3", "Finding Nemo", "Inside Out", "Spirited Away", "Monsters, Inc."], + "Esperado: ['Toy Story 3', 'Finding Nemo', 'Inside Out', 'Spirited Away', 'Monsters, Inc.']", + ) + self.assertEqual(pixar, 5, "Probando que pixar esté asignado correctamente.") + + + myTests().main() diff --git a/293/_sources/lectures/TWP45/TWP45_3_en.rst.txt b/293/_sources/lectures/TWP45/TWP45_3_en.rst.txt new file mode 100644 index 0000000000..6b0fdded10 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_3_en.rst.txt @@ -0,0 +1,156 @@ +Testing the TasteDive API +============================ + +TasteDive is a tool that: + + helps you discover new music, movies, TV shows, books, authors, games, + podcasts, and people with shared interests. + -- TasteDive + +In the following exercise, we will use the TasteDive API to search for works or artists similar to another of our choice. +The documentation for the `TasteDive API `_. + +.. activecode:: ac_l45_3a_en + :nocodelens: + :language: python + + In this case, we will use the ``requests`` library to make the API request. The base url + is ``"https://tastedive.com/api/similar"``. To this url, a parameter ``q`` with the + value of the artist Ariana Grande will be passed. Finally, the url will look like this: ``"https://tastedive.com/api/similar?q=ariana+grande"``. + Note that after the base url, a ``?`` is written to indicate that the parameters follow. + + ~~~~ + import requests + import json + + api_url = "https://tastedive.com/api/similar" + proxy = "https://cors.bridged.cc/" + + # The parameters that will be passed to the url are written inside a dictionary + parameters = {"q": "ariana grande"} + + # We request the data from the api + response = requests.get(proxy + api_url, params=parameters) + + # Now we print the url + print(response.url) + print() + + # We transform the json-formatted data to Python data + data = json.loads(response.text) + + print(data) + + +In the previous example, you could see that the API returns text, which if passed through ``json.loads`` +transforms into a Python dictionary. However, it is not entirely readable. This can be solved with +``json.dumps``. + +.. activecode:: ac_l45_3b_en + :language: python3 + :python3_interpreter: brython + + + Now, we will request information about the band Coldplay. This time we will print the data in a + readable format. We will use ``urllib`` to make the request. + + ~~~~ + import urllib.request + import urllib.parse + import json + + api_url = "https://tastedive.com/api/similar?" + proxy = "https://cors.bridged.cc/" + # The following line is for the url parameters + parameters = urllib.parse.urlencode({"q": "coldplay"}) + + request = urllib.request.urlopen(proxy + api_url + parameters) + data = json.loads(request.read()) + + # We print the data in a user-readable format + print(json.dumps(data, indent=4)) + + # We can see that the api returned 20 results related to the request + print(len(data["Similar"]["Results"])) + + +| + +The following exercise comes with automatic grading. + +.. activecode:: ac_l45_3c_en + :nocodelens: + :language: python + + Now we will ask TasteDive for the movie Coco. Then the dictionary ``parameters`` should have the + value ``"Coco"`` assigned to the key ``"q"``. Additionally, this time we only want 5 results instead of 20. + For this, there is a parameter called ``"limit"``, which can be assigned to the number of results needed. + Another parameter that will be passed to the url will be ``"info"`` and its value will be 1. This will make + the results come with extra text with information about the movie. + + First, you will request from the API what was described above, and save this in the variable ``request``. + In another variable, ``request_url``, save the url of the request. Then, assign the data to the variable ``data``. + Next, assign the variable ``results`` the number of results that the request returned + (as was done in the previous example). Because we set a limit, this number should match the limit. + + Now, you will create the list ``similar_movies``. Inside ``data`` you have a dictionary of dictionaries + and lists. What you will do is to search through the sets within which are the names of the movies + similar to Coco, and you will add the names of those movies to ``similar_movies``. There should be 5 in total. + **Hint**: the movie data is located within ``data["Similar"]["Results"]``, and the key to access it is ``"Name"``. + + Lastly, you will search for the number of times the word ``"Pixar"`` appears in the information texts of the + movies related to Coco. You will save that number in the variable ``pixar``. **Hint**: ``"wTeaser"`` is the + key that stores the text. This key is located in the same dictionary as the movie names. + + ~~~~ + import requests + import json + + api_url = "https://tastedive.com/api/similar" + proxy = "https://cors.bridged.cc/" + + # Add the parameters + parameters = {} + + # Complete the code + request = + request_url = + data = + + # Assign the variable results + + # print(f"results: {results}") + + # Create similar_movies + # Use a for loop to find the similar movies and add them + # to the corresponding variable + + # print(f"Movies: {similar_movies} len: {len(similar_movies)}") + + pixar = 0 + # Find the number of occurrences of "Pixar" within the data + + # print(f"Pixar: {pixar}") + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual( + request_url, + "https://cors.bridged.cc/https://tastedive.com/api/similar?q=Coco&limit=5&info=1", + "Testing that the url is: https://cors.bridged.cc/https://tastedive.com/api/similar?q=Coco&limit=5&info=1", + ) + self.assertEqual(results, 5, "Testing that results is assigned correctly.") + self.assertEqual(len(similar_movies), 5, "Testing that similar_movies are: 5") + self.assertEqual( + similar_movies, + ["Toy Story 3", "Finding Nemo", "Inside Out", "Spirited Away", "Monsters, Inc."], + "Expected: ['Toy Story 3', 'Finding Nemo', 'Inside Out', 'Spirited Away', 'Monsters, Inc.']", + ) + self.assertEqual(pixar, 5, "Testing that pixar is assigned correctly.") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/lectures/TWP45/TWP45_4.rst.txt b/293/_sources/lectures/TWP45/TWP45_4.rst.txt new file mode 100644 index 0000000000..27e9990108 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_4.rst.txt @@ -0,0 +1,67 @@ +Probando la API de University Domains +===================================== + +`University Domains and Names Data List & API `_ es una API que +contiene dominios, nombres y países de la mayoría de las universidades del mundo. + +.. activecode:: ac_l45_4a + :language: python3 + :python3_interpreter: brython + + Veamos un ejemplo de cómo usar esta API. Le vamos a pedir las universidades de Turquía que tengan + en su nombre la palabra **"middle"**. + + ~~~~ + import urllib.request + import urllib.parse + import json + + api_url = "https://cors.bridged.cc/http://universities.hipolabs.com/search?" + parametros = urllib.parse.urlencode({"name": "middle", "country": "turkey"}) + + solicitud = urllib.request.urlopen(api_url + parametros) + datos_json = json.loads(solicitud.read()) + + print(json.dumps(datos_json, indent=4)) + + +.. activecode:: ac_l45_4b + :nocodelens: + :language: python + + Busquemos todas las universidades en Colombia. + + ~~~~ + import requests + import json + + api_url = "https://cors.bridged.cc/http://universities.hipolabs.com/search" + parametros = {"country": "colombia"} + + solicitud = requests.get(api_url, params=parametros) + solicitud = json.loads(solicitud.text) + + universidades = [] + + for universidad in solicitud: + universidades.append(universidad["name"]) + + print(universidad["name"]) + + print("----------------------------------------------") + print(f"Hay {len(universidades)} universidades registradas") + + +Aprendizajes +------------ + ++ Accedemos a **APIs** para buscar información que nos es útil. ++ Podemos solicitar la información con dos librerías de Python: ``urllib`` o ``requests``. ++ La librería ``json`` de Pyhton nos ayuda a transformar la respuesta de la API en un objeto + de Python, ya sea diccionario o lista, con el método ``loads``, mientras que el método ``dumps`` + hace lo contrario; transforma un objeto de Python en una cadena con formato JSON. ++ El método ``dumps`` de ``json`` es útil si queremos visualizar la respuesta de una API de manera + legible. Esto se logra con el argumento ``indent``. + + +| diff --git a/293/_sources/lectures/TWP45/TWP45_4_en.rst.txt b/293/_sources/lectures/TWP45/TWP45_4_en.rst.txt new file mode 100644 index 0000000000..fae855dda6 --- /dev/null +++ b/293/_sources/lectures/TWP45/TWP45_4_en.rst.txt @@ -0,0 +1,64 @@ +Testing the University Domains API +================================== + +`University Domains and Names Data List & API `_ is an API that contains +domains, names, and countries of most universities around the world. + +.. activecode:: ac_l45_4a_en + :language: python3 + :python3_interpreter: brython + + Let's see an example of how to use this API. We will ask for universities in Turkey that have + the word **"middle"** in their name. + + ~~~~ + import urllib.request + import urllib.parse + import json + + api_url = "https://cors.bridged.cc/http://universities.hipolabs.com/search?" + params = urllib.parse.urlencode({"name": "middle", "country": "turkey"}) + + request = urllib.request.urlopen(api_url + params) + json_data = json.loads(request.read()) + + print(json.dumps(json_data, indent=4)) + + +.. activecode:: ac_l45_4b_en + :nocodelens: + :language: python + + Let's find all the universities in Colombia. + + ~~~~ + import requests + import json + + api_url = "https://cors.bridged.cc/http://universities.hipolabs.com/search" + params = {"country": "colombia"} + + request = requests.get(api_url, params=params) + request = json.loads(request.text) + + universities = [] + + for university in request: + universities.append(university["name"]) + + print(university["name"]) + + print("----------------------------------------------") + print(f"There are {len(universities)} registered universities") + + +Learnings +--------- + ++ We access **APIs** to search for information that is useful for us. ++ We can request information with two Python libraries: ``urllib`` or ``requests``. ++ The ``json`` library helps us transform the API's response into a Python object, either a dictionary or a list, with the ``loads`` method, while the ``dumps`` method does the opposite; transforms a Python object into a JSON formatted string. ++ The ``dumps`` method of ``json`` is useful if we want to visualize the response of an API in a readable way. This is achieved with the ``indent`` argument. + + +| \ No newline at end of file diff --git a/293/_sources/lectures/TWP45/toctree.rst.txt b/293/_sources/lectures/TWP45/toctree.rst.txt new file mode 100644 index 0000000000..3e914c073b --- /dev/null +++ b/293/_sources/lectures/TWP45/toctree.rst.txt @@ -0,0 +1,20 @@ +==================== +Hackeando con Python +==================== + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP45_1.rst + TWP45_2.rst + TWP45_3.rst + TWP45_4.rst diff --git a/293/_sources/lectures/TWP45/toctree_en.rst.txt b/293/_sources/lectures/TWP45/toctree_en.rst.txt new file mode 100644 index 0000000000..0e16d6f85a --- /dev/null +++ b/293/_sources/lectures/TWP45/toctree_en.rst.txt @@ -0,0 +1,20 @@ +=================== +Hacking with Python +=================== + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP45_1_en.rst + TWP45_2_en.rst + TWP45_3_en.rst + TWP45_4_en.rst diff --git a/293/_sources/lectures/TWP47/TWP47_1.rst.txt b/293/_sources/lectures/TWP47/TWP47_1.rst.txt new file mode 100644 index 0000000000..1d0eb1173c --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_1.rst.txt @@ -0,0 +1,94 @@ +Programacion Modular +==================== + + +.. image:: ../img/TWP47_001.png + :height: 11.865cm + :width: 21.001cm + :align: center + :alt: + + +Archivo Transactions.txt +------------------------ + + +.. image:: ../img/TWP47_002.png + :height: 9.515cm + :width: 22.859cm + :align: center + :alt: + + +Venta Salgados +-------------- + +.. code-block:: python + + def salva_transacao(precio, tarjeta_de_credito, descripcion): + file = open('transacoes.txt',"a") + file.write("%16s%07d%16s\n" %(tarjeta_de_credito,precio*100,descripcion)) + file.close() + + articulos = ["Sfiha","Cocina","Pastel","Pan de queso"] + precios = [1.50,2.20,1.80,1.20] + corriendo = True + + while corriendo: + opción = 1 + for elegir in alrticulos : + print(str(opcion) + "." + elegir) + opcao += 1 + print(str(opcion) + ".Finalizar") + elegir = int(input("Escoja una opción: ")) + if elegir == opcion: + #escolheu a ultima opcion Finalizar + corriendo = False + else: + credito = input("Número de tarjeta de crédito: ") + guardar_transacción(precios[elegir-1],tarjeta,articulos[elegir-1]) + + +.. image:: ../img/TWP47_004.jpg + :height: 11.112cm + :width: 15.768cm + :align: center + :alt: + + ++ Problemas: el banco rechazó el archivo de transacción completo para el período + ¡de mañana! ++ Todas las tarjetas no eran válidas ++ ¡Los precios eran demasiado altos: donut vendido por R $ 50.791,42! ++ En los otros períodos no hubo problema. Que paso + +.. image:: ../img/TWP47_005.png + :height: 5.952cm + :width: 10.08cm + :align: center + :alt: + + +.. image:: ../img/TWP47_006.png + :height: 11.945cm + :width: 22.859cm + :align: center + :alt: + + ++ ¡El banco cambió el orden de los datos! [Precio / Tarjeta / Artículo] + +.. image:: ../img/TWP47_007.png + :height: 4.001cm + :width: 22.802cm + :align: center + :alt: + + +.. image:: ../img/TWP47_008.jpg + :height: 12.571cm + :width: 19.998cm + :align: center + :alt: + + diff --git a/293/_sources/lectures/TWP47/TWP47_1_en.rst.txt b/293/_sources/lectures/TWP47/TWP47_1_en.rst.txt new file mode 100644 index 0000000000..144d4764da --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_1_en.rst.txt @@ -0,0 +1,87 @@ +Modular Programming +==================== + +.. image:: ../img/TWP47_001.png + :height: 11.865cm + :width: 21.001cm + :align: center + :alt: + +Transaction File Transactions.txt +---------------------------------- + +.. image:: ../img/TWP47_002.png + :height: 9.515cm + :width: 22.859cm + :align: center + :alt: + +Sale of Salgados +----------------- + +.. code-block:: python + + def save_transaction(price, credit_card, description): + file = open('transactions.txt',"a") + file.write("%16s%07d%16s\n" %(credit_card,price*100,description)) + file.close() + + articles = ["Sfiha","Cocina","Pastel","Pan de queso"] + prices = [1.50,2.20,1.80,1.20] + running = True + + while running: + option = 1 + for choose in articles: + print(str(option) + "." + choose) + option += 1 + print(str(option) + ".Finalizar") + choose = int(input("Escoja una opción: ")) + if choose == option: + #escolheu a ultima opcion Finalizar + running = False + else: + credit = input("Número de tarjeta de crédito: ") + save_transaction(prices[choose-1],credit,articles[choose-1]) + + +.. image:: ../img/TWP47_004.jpg + :height: 11.112cm + :width: 15.768cm + :align: center + :alt: + + ++ Issues: the bank rejected the entire transaction file for the next day period! ++ Not all credit cards were valid ++ Prices were too high: donut sold for R $ 50,791.42! ++ There were no issues in the other periods. What happened + +.. image:: ../img/TWP47_005.png + :height: 5.952cm + :width: 10.08cm + :align: center + :alt: + + +.. image:: ../img/TWP47_006.png + :height: 11.945cm + :width: 22.859cm + :align: center + :alt: + + ++ The bank changed the order of the data! [Price / Credit Card / Article] + +.. image:: ../img/TWP47_007.png + :height: 4.001cm + :width: 22.802cm + :align: center + :alt: + + +.. image:: ../img/TWP47_008.jpg + :height: 12.571cm + :width: 19.998cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP47/TWP47_2.rst.txt b/293/_sources/lectures/TWP47/TWP47_2.rst.txt new file mode 100644 index 0000000000..274e84f484 --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_2.rst.txt @@ -0,0 +1,88 @@ +Venta Salgados por turnos +========================= + +Venta Salgados Tarde / Noche +---------------------------- + +.. code-block:: python + + def guardar_transacción(precio, tarjeta_de_credito, descripcion): + file = open('transacoes.txt',"a") + file.write("%16s%07d%16s\n" %(tarjeta_de_credito,precio*100,descripcion)) + file.close() + + articulos = ["Esfiha","Cocina","Pastel","Pan de queso"] + precios = [1.50,2.20,1.80,1.20] + corriendo = True + + while corriendo: + opcion = 1 + for elegir in articulos: + print(str(opcion) + "." + elegir) + opcion += 1 + print(str(opcion) + ".Finalizar") + elegir = int(input("eliga una opcion ")) + if elegir == opcion: + #la última opción Finalizar + corriendo = False + else: + tarjeta = input("Número de tarjeta de crédit") + guardar_transacción(precios[elegir-1],tarjeta,articulos[elegir-1]) + + + ++ Formato corregido por el alumno! + + +Venta Salgados Mañana +--------------------- + +.. code-block:: python + + def guardar_transacción(precio, tarjeta_de_credito, descripcion): + file = open('transacoes.txt',"a") + file.write("%16s%07d%16s\n" %(tarjeta_de_credito,precio*100,descripcion)) + file.close() + + articulos = ["Sfiha","Cocina","Pastel","Pan de queso"] + precios = [1.50,2.20,1.80,1.20] + corriendo = True + + while corriendo: + opcion = 1 + for elegir in articulos: + print(str(opcion) + "." + elegir) + opcion += 1 + print(str(opcion) + ".Finalizar") + elegir = int(input("Eliga una opcion: ")) + if elegir == opcion: + #eligió la última opción + corriendo = False + else: + tarjeta = input("Número de tarjeta de crédito: ") + guardar_transacción(precios[elegir-1],tarjeta,articulos[elegir-1]) + ++ Productos modificados, ¡pero olvidé el formato! + + +Módulo banco.py +--------------- + + +.. image:: ../img/TWP47_011.jpg + :height: 12.571cm + :width: 18.267cm + :align: center + :alt: + + +.. code-block:: python + + def salva_transacao(precio, tarjeta_de_credito, descripcion): + file = open('transacoes.txt',"a") + file.write("%16s%07d%16s\n" %(tarjeta_de_credito,precio*100,descripcion)) + file.close() + + + ++ Nota: dejar en el mismo directorio que los programas de mañana y tarde / noche diff --git a/293/_sources/lectures/TWP47/TWP47_2_en.rst.txt b/293/_sources/lectures/TWP47/TWP47_2_en.rst.txt new file mode 100644 index 0000000000..622bf39dfe --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_2_en.rst.txt @@ -0,0 +1,86 @@ +Sale of Salgados by Shifts +=========================== + +Afternoon / Evening Salgados Sale +--------------------------------- + +.. code-block:: python + + def save_transaction(price, credit_card, description): + file = open('transactions.txt',"a") + file.write("%16s%07d%16s\n" %(credit_card,price*100,description)) + file.close() + + items = ["Esfiha","Coxinha","Pastel","Cheese bread"] + prices = [1.50,2.20,1.80,1.20] + running = True + + while running: + option = 1 + for item in items: + print(str(option) + "." + item) + option += 1 + print(str(option) + ".Finish") + choice = int(input("Choose an option: ")) + if choice == option: + #the last option, Finish + running = False + else: + card = input("Credit card number: ") + save_transaction(prices[choice-1],card,items[choice-1]) + + + ++ Corrected format by the student! + + +Morning Salgados Sale +--------------------- + +.. code-block:: python + + def save_transaction(price, credit_card, description): + file = open('transactions.txt',"a") + file.write("%16s%07d%16s\n" %(credit_card,price*100,description)) + file.close() + + items = ["Sfiha","Coxinha","Pastel","Cheese bread"] + prices = [1.50,2.20,1.80,1.20] + running = True + + while running: + option = 1 + for item in items: + print(str(option) + "." + item) + option += 1 + print(str(option) + ".Finish") + choice = int(input("Choose an option: ")) + if choice == option: + #chose the last option + running = False + else: + card = input("Credit card number: ") + save_transaction(prices[choice-1],card,items[choice-1]) + ++ Products modified, but I forgot about the format! + + +Module bank.py +-------------- + +.. image:: ../img/TWP47_011.jpg + :height: 12.571cm + :width: 18.267cm + :align: center + :alt: + +.. code-block:: python + + def save_transaction(price, credit_card, description): + file = open('transactions.txt',"a") + file.write("%16s%07d%16s\n" %(credit_card,price*100,description)) + file.close() + + + ++ Note: leave in the same directory as the morning and afternoon/evening programs. \ No newline at end of file diff --git a/293/_sources/lectures/TWP47/TWP47_3.rst.txt b/293/_sources/lectures/TWP47/TWP47_3.rst.txt new file mode 100644 index 0000000000..c60fcb4561 --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_3.rst.txt @@ -0,0 +1,54 @@ +Nuevo programa por turnos +========================= + +Nuevo programa de la mañana +--------------------------- + + +.. code-block:: python + + from banco import * + + articulos = ["Bauru","X ensalada","Calafrango"] + precios = [2.50,3.0,2.20] + corriendo = True + + while corriendo: + opcion = 1 + for elegir in articulos: + print(str(opcion) + "." + elegir) + opcao += 1 + print(str(opcion) + ".Finalizar") + elegir = int(input("Elija una opcion: ")) + if elegir == opcion: + # eligió la última opción Finalizar + corriendo = False + else: + tarjeta = input("Número de tarjeta de crédito: ") + guardar_transacción(precios[elegir-1],tarjeta,articulos[elegir-1]) + +Nuevo programa de tarde / noche +------------------------------- + + +.. code-block:: python + + from banco import * + + articulos = ["Sfiha","Cocina","Pastel","Pan de queso"] + precios = [1.50,2.20,1.80,1.20] + corriendo = True + + while corriendo: + opcion = 1 + for elegir in articulos: + print(str(opcion) + "." + elegir) + opcion += 1 + print(str(opcion) + ".Finalizar") + elegir = int(input("Elige una opcion: ")) + if elegir == opcion: + # eligió la última opción Finalizar + corriendo = False + else: + tarjeta = input("Número de tarjeta de crédito: ") + guardar_transacción(precios[elegir-1],cartao,articulos[elegir-1]) diff --git a/293/_sources/lectures/TWP47/TWP47_3_en.rst.txt b/293/_sources/lectures/TWP47/TWP47_3_en.rst.txt new file mode 100644 index 0000000000..c98ca3f75f --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_3_en.rst.txt @@ -0,0 +1,52 @@ +New Shift Program +================== + +New Morning Program +-------------------- + +.. code-block:: python + + from bank import * + + articles = ["Bauru","X Salad","Calafrango"] + prices = [2.50,3.0,2.20] + running = True + + while running: + option = 1 + for select in articles: + print(str(option) + "." + select) + option += 1 + print(str(option) + ".Finish") + select = int(input("Choose an option: ")) + if select == option: + # chose the last option Finish + running = False + else: + card = input("Credit card number: ") + save_transaction(prices[select-1],card,articles[select-1]) + +New Afternoon / Night Program +------------------------------ + +.. code-block:: python + + from bank import * + + articles = ["Sfiha","Kitchen","Cake","Cheese Bread"] + prices = [1.50,2.20,1.80,1.20] + running = True + + while running: + option = 1 + for select in articles: + print(str(option) + "." + select) + option += 1 + print(str(option) + ".Finish") + select = int(input("Choose an option: ")) + if select == option: + # chose the last option Finish + running = False + else: + card = input("Credit card number: ") + save_transaction(prices[select-1],card,articles[select-1]) \ No newline at end of file diff --git a/293/_sources/lectures/TWP47/TWP47_4.rst.txt b/293/_sources/lectures/TWP47/TWP47_4.rst.txt new file mode 100644 index 0000000000..2180a297ff --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_4.rst.txt @@ -0,0 +1,51 @@ +Descuentos +========== + ++ ¡Ahora bajo una nueva dirección, las sales en FATEC tendrán un 10% de descuento! ++ Para esto, se creará un módulo fatec.py ++ Inicialmente, el descuento será del 10% para todos los bocadillos + + +.. image:: ../img/TWP47_015.png + :height: 1.799cm + :width: 9.524cm + :align: center + :alt: + + +.. code-block:: python + + from banco import * + from fatec import * + + articulos = ["Sfiha","Cocina","Pastel","Pan de queso"] + precios = [1.50,2.20,1.80,1.20] + corriendo = True + + while corriendo: + opcion = 1 + for elegir in articulos: + print(str(opcion) + "." + elegir) + opcion += 1 + print(str(opcion) + ".Finalizar") + elegir = int(input("Elige una opcion")) + if elegir == opcion: + # eligió la última opción Finalizar + corriendo = False + else: + tarjeta = input("Numero de tarjeta de credito: ") + precio = descuento(precios[elegir-1]) + guardar_transacción(precio,tarjeta,articulos[elegir-1]) + + + ++ Tendremos un descuento adicional del 50% para pasteles a causa de + colonia japonesa ++ Nuevo módulo japa.py + + +.. image:: ../img/TWP47_017.png + :height: 2.199cm + :width: 12.158cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP47/TWP47_4_en.rst.txt b/293/_sources/lectures/TWP47/TWP47_4_en.rst.txt new file mode 100644 index 0000000000..41a37ba2d4 --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_4_en.rst.txt @@ -0,0 +1,50 @@ +Discounts +========== + ++ Now under a new management, sales at FATEC will have a 10% discount! ++ For this, a fatec.py module will be created ++ Initially, the discount will be 10% for all sandwiches + + +.. image:: ../img/TWP47_015.png + :height: 1.799cm + :width: 9.524cm + :align: center + :alt: + + +.. code-block:: python + + from banco import * + from fatec import * + + items = ["Sfiha","Cocina","Pastel","Pan de queso"] + prices = [1.50,2.20,1.80,1.20] + running = True + + while running: + option = 1 + for choice in items: + print(str(option) + "." + choice) + option += 1 + print(str(option) + ".Finish") + choice = int(input("Choose an option")) + if choice == option: + # Chose the last option - "Finish" + running = False + else: + card_number = input("Credit card number: ") + price = discount(prices[choice-1]) + save_transaction(price, card_number, items[choice-1]) + + + ++ We will have an additional 50% discount for cakes due to the Japanese colony ++ New japa.py module + + +.. image:: ../img/TWP47_017.png + :height: 2.199cm + :width: 12.158cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP47/TWP47_5.rst.txt b/293/_sources/lectures/TWP47/TWP47_5.rst.txt new file mode 100644 index 0000000000..3e859851b2 --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_5.rst.txt @@ -0,0 +1,59 @@ +¡Los nombres son iguales! ¿Y ahora? +=================================== + + +.. image:: ../img/TWP47_018.png + :height: 10.722cm + :width: 19.917cm + :align: center + :alt: + + +Nombres completos +----------------- + ++ La solución es adoptar los nombres completos + + +.. code-block:: python + + from banco import * + import fatec + import japa + + articulos = ["Sfiha","Cocina","Pastel","Pan de queso"] + precios = [1.50,2.20,1.80,1.20] + corriendo = True + + while corriendo: + opcion = 1 + for elegir in articulos: + print(str(opcion) + "." + elegir) + opcion += 1 + print(str(opcion) + ".Finalizar") + elegir = int(input("Elige una opcion")) + if elegir == opcion: + # eligió la última opción Finalizar + corriendo = False + else: + tarjeta = input("Número de tarjeta de crédito: ") + precio = fatec.descento(precios[elegir - 1]) + if itens[elegir - 1] == "Pastel": + precio = japa.descento(precio) + (precio,tarjeta,articulos[elegir-1]) + + +Resultado +--------- + +.. image:: ../img/TWP47_020.png + :height: 11.324cm + :width: 22.859cm + :align: center + :alt: + +.. image:: ../img/TWP47_021.png + :height: 11.324cm + :width: 22.859cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP47/TWP47_5_en.rst.txt b/293/_sources/lectures/TWP47/TWP47_5_en.rst.txt new file mode 100644 index 0000000000..adf742b372 --- /dev/null +++ b/293/_sources/lectures/TWP47/TWP47_5_en.rst.txt @@ -0,0 +1,57 @@ +The names are the same! Now what? +================================== + +.. image:: ../img/TWP47_018.png + :height: 10.722cm + :width: 19.917cm + :align: center + :alt: + +Full Names +---------- + ++ The solution is to adopt full names. + + +.. code-block:: python + + from bank import * + import fatec + import japa + + items = ["Sfiha", "Cuisine", "Cake", "Cheese Bread"] + prices = [1.50, 2.20, 1.80, 1.20] + running = True + + while running: + option = 1 + for choose in items: + print(str(option) + "." + choose) + option += 1 + print(str(option) + ".Finish") + choose = int(input("Choose an option")) + if choose == option: + # chose the last option Finish + running = False + else: + card = input("Credit Card Number: ") + price = fatec.discount(prices[choose - 1]) + if items[choose - 1] == "Cake": + price = japa.discount(price) + (price, card, items[choose-1]) + + +Result +------ + +.. image:: ../img/TWP47_020.png + :height: 11.324cm + :width: 22.859cm + :align: center + :alt: + +.. image:: ../img/TWP47_021.png + :height: 11.324cm + :width: 22.859cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP47/toctree.rst.txt b/293/_sources/lectures/TWP47/toctree.rst.txt new file mode 100644 index 0000000000..792c36dfc4 --- /dev/null +++ b/293/_sources/lectures/TWP47/toctree.rst.txt @@ -0,0 +1,22 @@ +======= +Módulos +======= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP47_1.rst + TWP47_2.rst + TWP47_3.rst + TWP47_4.rst + TWP47_5.rst diff --git a/293/_sources/lectures/TWP47/toctree_en.rst.txt b/293/_sources/lectures/TWP47/toctree_en.rst.txt new file mode 100644 index 0000000000..cd25092779 --- /dev/null +++ b/293/_sources/lectures/TWP47/toctree_en.rst.txt @@ -0,0 +1,22 @@ +======= +Modules +======= + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP47_1_en.rst + TWP47_2_en.rst + TWP47_3_en.rst + TWP47_4_en.rst + TWP47_5_en.rst diff --git a/293/_sources/lectures/TWP50/TWP50_1.rst.txt b/293/_sources/lectures/TWP50/TWP50_1.rst.txt new file mode 100644 index 0000000000..e9a3ca73fc --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_1.rst.txt @@ -0,0 +1,105 @@ +Introducción a una interfaz gráfica +=================================== + ++ En la programación no basta con hacer solamente el código. ++ No es suficiente para trabajar, también debe ser atractivo para el usuario. ++ Las interfaces basadas en texto funcionan, pero son limitadas y antiguas. ++ Motivado a esto, se necesita crear interfaces gráficas de usuario, también conocida por sus iniciales del inglés GUI *graphical user interface* ++ Las interfaces gráficas de usuario podemos encontrarlas en diferentes sitios: + + En programas para la computadora, por ejemplo, una muy conocida es el programa Office. Estas interfaces las podemos llamar *interfaces de escritorio*. + + También podemos encontrar interfaces que se ven dentro del navegador, como por ejemplo la página de Facebook, estas interfaces podemos llamarlas *interfaces web*. + + Por último, encontramos interfaces en las aplicaciones para nuestros teléfonos inteligentes, un ejemplo es la aplicación Whatsapp, representando a las *interfaces móviles*. ++ En Python existen diferentes herramientas y librerías para la creación de interfaces, entre las conocidas para crear interfaces de escritorio se encuentran las librerías ``tkinter`` y ``PyQt``. ++ Ya que nuestro objetivo es crear interfaces dentro del navegador, utilizaremos nuevamente ``brython``. ++ Brython permite a través de su sintaxis la capacidad de crear interfaces gráficas simples. ++ Crearemos en este ejercicio el **Show de preguntas Zombis**. + +Show de preguntas Zombis +------------------------ + ++ Es un juego con diferentes opciones. ++ La *opción 1* es para la respuesta correcta y la *opción 2* para la respuesta incorrecta. ++ El programa tendrá un efecto de sonido para cada respuesta. ++ El programa debe contar cuántas respuestas correctas e incorrectas hubo. ++ Finalmente presione 0 para terminar. + + +Reproduciendo un audio +---------------------- + ++ Comencemos hacer la lógica de reproducir un audio. ++ Hay diversas formas de hacerlo, una opción puede ser con la librería ``pygame`` entre otras. ++ Nuevamente usaremos el modulo de Brython. ++ El código de abajo genera un elemento de HTML llamado ``audio``. ++ En está `página `_ puedes obtener sonidos libres que puedes usar en el programa. + + Solo necesitas copiar y pegar la url del sónido que te guste. + + +.. activecode:: ac_l50_1a + :nocodelens: + :language: python3 + :python3_interpreter: brython + + + from browser import document, html + + url_audio = "" # Agrega un enlace de un audio para reproducirlo + print("Creando el elemento audio") + document <= html.AUDIO(id="audio", src=url_audio, controls=True) + ++ Notaste que se creó el elemento de audio con los controles para reproducirlo y detenerlo. ++ Puedes agregar cuantos sonidos quieras. ++ ¿Pero cómo manejo por el programa cuándo se reproduce y cuándo se detiene el sonido? + + Vamos a enlazar eventos para poder lograrlo. + +.. activecode:: ac_l50_1b + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html, timer + + + def crear_elemento(url_audio, nombre_audio): + print(f"Creando el elemento audio {url_audio}") + document <= html.AUDIO(id=nombre_audio, src=url_audio) + + # Función para iniciar el audio + def iniciar_audio(elemento): + document[elemento].play() + + # Función para pausar el audio + def pausar_audio(elemento): + document[elemento].pause() + + + # Sonido de campana + crear_elemento("https://bigsoundbank.com/UPLOAD/ogg/0001.ogg", "audio_1") + # Sonido de golpeteo + crear_elemento("https://bigsoundbank.com/UPLOAD/ogg/0005.ogg", "audio_2") + + # Iniciar los audios + iniciar_audio("audio_1") + iniciar_audio("audio_2") + + # Reproduce solamente 10 segundos del audio luego se detiene + timer.set_timeout(pausar_audio, 10000, "audio_1") + + # Reproduce solamente 5 segundos del audio luego se detiene + timer.set_timeout(pausar_audio, 5000, "audio_2") + +.. image:: ../img/TWP50_004.png + :height: 9.626cm + :width: 6.118cm + :align: center + :alt: + ++ Se oyen muy bien los audios. ++ Ahora que el audio está funcionando, ¡hagamos el Show de preguntas Zombis! + +.. image:: ../img/TWP50_007.jpg + :height: 7.487cm + :width: 10.688cm + :align: center + :alt: + diff --git a/293/_sources/lectures/TWP50/TWP50_1_en.rst.txt b/293/_sources/lectures/TWP50/TWP50_1_en.rst.txt new file mode 100644 index 0000000000..72dea04b2e --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_1_en.rst.txt @@ -0,0 +1,103 @@ +Introduction to a Graphical User Interface +=========================================== + ++ In programming, just writing code is not enough. ++ It is not enough for it to work; it must also be attractive to the user. ++ Text-based interfaces work, but they are limited and outdated. ++ Motivated by this, it is necessary to create graphical user interfaces (GUIs). ++ GUIs can be found in different places: + + In computer programs, for example, a well-known one is the Office program. These interfaces can be called *desktop interfaces*. + + We can also find interfaces that are seen within the browser, such as the Facebook page. These interfaces can be called *web interfaces*. + + Finally, we find interfaces in applications for our smartphones, an example being the Whatsapp application, representing *mobile interfaces*. ++ In Python, there are different tools and libraries for creating interfaces, including the well-known ``tkinter`` and ``PyQt`` libraries for creating desktop interfaces. ++ Since our goal is to create interfaces within the browser, we will use ``brython`` again. ++ Brython allows the creation of simple graphical interfaces through its syntax. ++ In this exercise, we will create the **Zombie Quiz Show**. + +Zombie Quiz Show +---------------- + ++ It is a game with different options. ++ *Option 1* is for the correct answer and *Option 2* is for the incorrect answer. ++ The program will have a sound effect for each answer. ++ The program must keep track of how many correct and incorrect answers there were. ++ Finally, press 0 to finish. + +Playing Audio +------------- + ++ Let's start by creating the logic for playing audio. ++ There are various ways to do this; one option might be to use the ``pygame`` library, among others. ++ Again, we will use the Brython module. ++ The code below generates an HTML element called ``audio``. ++ On this `page `_, you can obtain free sounds that you can use in the program. + + You just need to copy and paste the url of the sound you like. + + +.. activecode:: ac_l50_1a_en + :nocodelens: + :language: python3 + :python3_interpreter: brython + + + from browser import document, html + + url_audio = "" # Add a link of an audio to play it + print("Creating the audio element") + document <= html.AUDIO(id="audio", src=url_audio, controls=True) + ++ You noticed that the audio element with controls to play and stop it was created. ++ You can add as many sounds as you want. ++ But how do I handle when the sound is played and stopped through the program? + + Let's link events to achieve it. + +.. activecode:: ac_l50_1b_en + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html, timer + + + def create_element(url_audio, audio_name): + print(f"Creating the audio element {url_audio}") + document <= html.AUDIO(id=audio_name, src=url_audio) + + # Function to play the audio + def play_audio(element): + document[element].play() + + # Function to pause the audio + def pause_audio(element): + document[element].pause() + + + # Bell sound + create_element("https://bigsoundbank.com/UPLOAD/ogg/0001.ogg", "audio_1") + # Knock sound + create_element("https://bigsoundbank.com/UPLOAD/ogg/0005.ogg", "audio_2") + + # Start the audios + play_audio("audio_1") + play_audio("audio_2") + + # Plays only 10 seconds of the audio, then stops + timer.set_timeout(pause_audio, 10000, "audio_1") + + # Plays only 5 seconds of the audio, then stops + timer.set_timeout(pause_audio, 5000, "audio_2") + +.. image:: ../img/TWP50_004.png + :height: 9.626cm + :width: 6.118cm + :align: center + :alt: + ++ The sounds are playing very well. ++ Now that audio is working, let's create the Zombie Quiz Show! + +.. image:: ../img/TWP50_007.jpg + :height: 7.487cm + :width: 10.688cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP50/TWP50_2.rst.txt b/293/_sources/lectures/TWP50/TWP50_2.rst.txt new file mode 100644 index 0000000000..29976a04ce --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_2.rst.txt @@ -0,0 +1,43 @@ +Show de preguntas Zombis +======================== + ++ Comencemos con la lógica del programa utilizando una interfaz de texto. ++ Recuerda los requerimientos: + + La *opción 1* es para la respuesta correcta y la *opción 2* para la respuesta incorrecta. + + Contar cuántas respuestas correctas e incorrectas hubo. + + La *opción 0* es para terminar. + +.. activecode:: ac_l50_2 + :nocodelens: + + correctas = incorrectas = 0 + + opcion = int(input("Seleccione: 1) Correcto 2) Incorrecto 0) Terminar")) + + # Mientras la opción no se cero acumular los valores + while opcion != 0: + if opcion == 1: + correctas = correctas + 1 + if opcion == 2: + incorrectas = incorrectas + 1 + opcion = int(input("Seleccione: 1) Correcto 2) Incorrecto 0) Terminar")) + + print(f"Correctas:{correctas} Incorrectas:{incorrectas}") + ++ Resultado + +.. image:: ../img/TWP50_006.png + :height: 7.989cm + :width: 15.027cm + :align: center + :alt: + +.. image:: ../img/TWP50_003.png + :height: 7.01cm + :width: 6.825cm + :align: center + :alt: + ++ ¡Perfecto! el jefe está contento funciona de maravilla. ++ Faltaría el requerimiento de los sonidos. ++ Sin embargo... ¿La interfaz de texto es nueva? diff --git a/293/_sources/lectures/TWP50/TWP50_2_en.rst.txt b/293/_sources/lectures/TWP50/TWP50_2_en.rst.txt new file mode 100644 index 0000000000..da47253e19 --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_2_en.rst.txt @@ -0,0 +1,43 @@ +Zombie Questions Show +====================== + ++ Let's start with the program logic using a text interface. ++ Remember the requirements: + + *Option 1* is for the correct answer and *Option 2* for the incorrect answer. + + Count how many correct and incorrect answers there were. + + *Option 0* is to terminate. + +.. activecode:: ac_l50_2_en + :nocodelens: + + correctas = incorrectas = 0 + + opcion = int(input("Select: 1) Correct 2) Incorrect 0) Terminate")) + + # While the option is not zero, accumulate the values + while opcion != 0: + if opcion == 1: + correctas = correctas + 1 + if opcion == 2: + incorrectas = incorrectas + 1 + opcion = int(input("Select: 1) Correct 2) Incorrect 0) Terminate")) + + print(f"Correct:{correctas} Incorrect:{incorrectas}") + ++ Result + +.. image:: ../img/TWP50_006.png + :height: 7.989cm + :width: 15.027cm + :align: center + :alt: + +.. image:: ../img/TWP50_003.png + :height: 7.01cm + :width: 6.825cm + :align: center + :alt: + ++ Perfect! The boss is happy, it works great. ++ The sounds requirement is still missing. ++ However... Is the text interface new? \ No newline at end of file diff --git a/293/_sources/lectures/TWP50/TWP50_3.rst.txt b/293/_sources/lectures/TWP50/TWP50_3.rst.txt new file mode 100644 index 0000000000..97cf1d65d6 --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_3.rst.txt @@ -0,0 +1,72 @@ +Ventana básica +============== + +.. image:: ../img/TWP50_008.jpg + :height: 13.801cm + :width: 12.79cm + :align: center + :alt: + ++ La interfaz de texto funciona, pero es muy limitada y antigua. ++ Por tanto, ahora que la lógica detrás del show funciona, creemos una interfaz de usuario y mejorar esta de texto. ++ Comencemos con una interfaz básica, nuevamente usando el modulo de ``brython``. + + Usaremos unas herramientas o widgets que se encuentran en Brython. + + Estas herramientas ya se encuentran implementadas. + + Permiten la creación de diálogos o pequeñas ventanas para interactuar con el usuario. + +Ventana con Brython +------------------- + +.. activecode:: ac_l50_3a + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html + from browser.widgets.dialog import Dialog + + # Creación de un dialogo con el título + d = Dialog("Show de preguntas Zombis", top=20, left=20) + + # Agrega elementos como botones y títulos + d.panel <= html.H3("Aprieta los botones", id="titulo_ventana", style=dict(textAlign="center")) + d.panel <= html.BUTTON("Correcto", id="btn_correcto") + d.panel <= html.BUTTON("Incorrecto", id="btn_incorrecto", style=dict(marginLeft="5em")) + ++ Pudiste notar que en la ventana básica los botones no hacían nada. ++ Es necesario enlazar un evento a cada botón. ++ Esto se denomina programación orientada a eventos. ++ Esperar a las acciones del usuario. + + +Capturando un evento +-------------------- + ++ Para capturar un evento de un botón es necesario crear una función. ++ En la función se encontrará toda la lógica que se quiere para el botón. ++ Crearemos una ventana nueva con un botón y vamos a capturar o enlazar un evento. ++ Mostraremos en pantalla un mensaje cada vez que el usuario presione el botón. + +.. activecode:: ac_l50_3b + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html + from browser.widgets.dialog import Dialog + + d = Dialog("Prueba capturando un evento", top=20, left=20) + + d.panel <= html.BUTTON("¡Apriétame!", id="btn_apretar", style=dict(margin="auto", display="block")) + + # Función controladora del evento, mostrando un mensaje + def apretar_boton(ev): + print("Apretaste el botón") + + document["btn_apretar"].bind("click", apretar_boton) + ++ Perfecto ya sabes como capturar eventos. ++ Puedes capturar eventos usando la función ``.bind()`` especificando el evento o utilizando una intrucción ``@bind`` también llamado decorador o *decorator*. + + Esta instrucción se escribe en una línea anterior a la función que realiza el botón. ++ Sabiendo está lógica podemos terminar el Show de preguntas Zombis. ++ Recuerda la reproducción de los sonidos y la lógica de las diferentes opciones. diff --git a/293/_sources/lectures/TWP50/TWP50_3_en.rst.txt b/293/_sources/lectures/TWP50/TWP50_3_en.rst.txt new file mode 100644 index 0000000000..64ffad60ac --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_3_en.rst.txt @@ -0,0 +1,72 @@ +Basic Window +============== + +.. image:: ../img/TWP50_008.jpg + :height: 13.801cm + :width: 12.79cm + :align: center + :alt: + ++ The text interface works, but it is very limited and outdated. ++ Therefore, now that the logic behind the show works, let's create a user interface and improve this text one. ++ Let's start with a basic interface, again using the ``brython`` module. + + We will use some tools or widgets that are found in Brython. + + These tools are already implemented. + + They allow the creation of dialogs or small windows to interact with the user. + +Window with Brython +------------------- + +.. activecode:: ac_l50_3a_en + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html + from browser.widgets.dialog import Dialog + + # Creating a dialog with a title + d = Dialog("Zombie Question Show", top=20, left=20) + + # Adding elements such as buttons and titles + d.panel <= html.H3("Press the buttons", id="window_title", style=dict(textAlign="center")) + d.panel <= html.BUTTON("Correct", id="btn_correct") + d.panel <= html.BUTTON("Incorrect", id="btn_incorrect", style=dict(marginLeft="5em")) + ++ You may have noticed that in the basic window the buttons did nothing. ++ It is necessary to link an event to each button. ++ This is called event-driven programming. ++ We need to wait for user actions. + + +Capturing an Event +-------------------- + ++ To capture an event from a button, it is necessary to create a function. ++ In the function, all the logic that is wanted for the button will be found. ++ We will create a new window with a button and we will capture or link an event. ++ We will show a message on the screen every time the user presses the button. + +.. activecode:: ac_l50_3b_en + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html + from browser.widgets.dialog import Dialog + + d = Dialog("Test capturing an event", top=20, left=20) + + d.panel <= html.BUTTON("Press me!", id="btn_press", style=dict(margin="auto", display="block")) + + # Event handling function, showing a message + def press_button(ev): + print("You pressed the button") + + document["btn_press"].bind("click", press_button) + ++ Perfect, now you know how to capture events. ++ You can capture events using the ``.bind()`` function specifying the event or using a ``@bind`` instruction, also called decorator. + + This instruction is written on a line previous to the button handling function. ++ Knowing this logic we can finish the Zombie Question Show. ++ Remember the reproduction of sounds and the logic of the different options. \ No newline at end of file diff --git a/293/_sources/lectures/TWP50/TWP50_4.rst.txt b/293/_sources/lectures/TWP50/TWP50_4.rst.txt new file mode 100644 index 0000000000..d827e60253 --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_4.rst.txt @@ -0,0 +1,144 @@ +Versión final del show de preguntas Zombis +========================================== + +.. activecode:: ac_l50_4a + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html + from browser.widgets.dialog import Dialog + + + def crear_elemento(url_audio, nombre_audio): + print(f"Creando el elemento audio {url_audio}") + document <= html.AUDIO(id=nombre_audio, src=url_audio) + + + def iniciar_audio(elemento): + document[elemento].play() + + + def pausar_audio(elemento): + document[elemento].pause() + + correctas = incorrectas = 0 + + # Sonido de correcto + crear_elemento("http://www.superluigibros.com/downloads/sounds/SNES/SMRPG/wav/smrpg_correct.wav", "correcto") + # Sonido de incorrecto + crear_elemento("https://bigsoundbank.com/UPLOAD/ogg/1684.ogg", "incorrecto") + + d = Dialog("Show de preguntas Zombis", top=20, left=20) + + d.panel <= html.H4("Aprieta los botones", id="titulo_ventana", style=dict(textAlign="center")) + d.panel <= html.BUTTON("Correcto", id="btn_correcto") + d.panel <= html.BUTTON("Incorrecto", id="btn_incorrecto", style=dict(marginLeft="5em")) + + def apretar_boton_correcto(ev): + global correctas + iniciar_audio("correcto") + correctas = correctas + 1 + print("Apretaste el botón correcto") + + def apretar_boton_incorrecto(ev): + global incorrectas + iniciar_audio("incorrecto") + incorrectas = incorrectas + 1 + print("Apretaste el botón incorrecto") + + document["btn_correcto"].bind("click", apretar_boton_correcto) + document["btn_incorrecto"].bind("click", apretar_boton_incorrecto) + ++ Falta algo importante. ++ ¡Los resultados de cada una de las opciones! + +.. image:: ../img/TWP50_013.jpg + :height: 15.793cm + :width: 11.6cm + :align: center + :alt: + ++ Cambiemos la ventana para agregar una etiqueta que cambie su valor. ++ El valor aumentará cada vez que se presione el botón respectivo + +.. activecode:: ac_l50_4b + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html, bind + from browser.widgets.dialog import Dialog + + + def crear_elemento(url_audio, nombre_audio): + print(f"Creando el elemento audio {url_audio}") + document <= html.AUDIO(id=nombre_audio, src=url_audio) + + + def iniciar_audio(elemento): + document[elemento].play() + + + def pausar_audio(elemento): + document[elemento].pause() + + + correctas = incorrectas = 0 + + # Sonido de correcto + crear_elemento("http://www.superluigibros.com/downloads/sounds/SNES/SMRPG/wav/smrpg_correct.wav", "correcto") + # Sonido de incorrecto + crear_elemento("https://bigsoundbank.com/UPLOAD/ogg/1684.ogg", "incorrecto") + + d = Dialog("Show de preguntas Zombis", top=20, left=20) + + d.panel <= html.H4( + "Aprieta los botones", id="titulo_ventana", style=dict(textAlign="center") + ) + d.panel <= html.SPAN( + str(correctas), id="contador_correctas", style=dict(paddingRight="2em") + ) + html.BUTTON("Correcto", id="btn_correcto") + d.panel <= html.BUTTON( + "Incorrecto", id="btn_incorrecto", style=dict(marginLeft="5em") + ) + html.SPAN( + str(incorrectas), id="contador_incorrectas", style=dict(paddingLeft="2em") + ) + + + @bind(document["btn_correcto"], "click") + def apretar_boton_correcto(ev): + global correctas + iniciar_audio("correcto") + correctas += 1 + document["contador_correctas"].textContent = str(correctas) + print("Apretaste el botón correcto") + + + @bind(document["btn_incorrecto"], "click") + def apretar_boton_incorrecto(ev): + global incorrectas + iniciar_audio("incorrecto") + incorrectas += 1 + document["contador_incorrectas"].textContent = str(incorrectas) + print("Apretaste el botón incorrecto") + ++ ¡Muy bien! ya todo funciona perfectamente. ++ Puedes cambiar el audio para cada opción. ++ El jefe está feliz por el Show de preguntas Zombis. + +.. image:: ../img/TWP50_017.jpg + :height: 14.861cm + :width: 15.801cm + :align: center + :alt: + + +Recuerda +-------- + ++ Uso de las funcionalidades con el componente de ``brython``. ++ No es la única forma de crear interfaces gráficas. + + Uso de la biblioteca de terceros: ``pygame`` y ``tkinter``. ++ Para manejar los eventos se usa un controlador de eventos. + + Controlador de eventos: función que se ejecuta cuando ocurre el evento. diff --git a/293/_sources/lectures/TWP50/TWP50_4_en.rst.txt b/293/_sources/lectures/TWP50/TWP50_4_en.rst.txt new file mode 100644 index 0000000000..a6aa1d81c7 --- /dev/null +++ b/293/_sources/lectures/TWP50/TWP50_4_en.rst.txt @@ -0,0 +1,144 @@ +Final version of the Zombies question show +========================================== + +.. activecode:: ac_l50_4a_en + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html + from browser.widgets.dialog import Dialog + + + def create_element(audio_url, audio_name): + print(f"Creating the audio element {audio_url}") + document <= html.AUDIO(id=audio_name, src=audio_url) + + + def start_audio(element): + document[element].play() + + + def pause_audio(element): + document[element].pause() + + correct = incorrect = 0 + + # Correct sound + create_element("http://www.superluigibros.com/downloads/sounds/SNES/SMRPG/wav/smrpg_correct.wav", "correct") + # Incorrect sound + create_element("https://bigsoundbank.com/UPLOAD/ogg/1684.ogg", "incorrect") + + d = Dialog("Zombies Question Show", top=20, left=20) + + d.panel <= html.H4("Press the buttons", id="window_title", style=dict(textAlign="center")) + d.panel <= html.BUTTON("Correct", id="btn_correct") + d.panel <= html.BUTTON("Incorrect", id="btn_incorrect", style=dict(marginLeft="5em")) + + def press_correct_button(ev): + global correct + start_audio("correct") + correct = correct + 1 + print("You pressed the correct button") + + def press_incorrect_button(ev): + global incorrect + start_audio("incorrect") + incorrect = incorrect + 1 + print("You pressed the incorrect button") + + document["btn_correct"].bind("click", press_correct_button) + document["btn_incorrect"].bind("click", press_incorrect_button) + ++ Something important is missing. ++ The results of each option! + +.. image:: ../img/TWP50_013.jpg + :height: 15.793cm + :width: 11.6cm + :align: center + :alt: + ++ Let's change the window to add a label that changes its value. ++ The value will increase every time the respective button is pressed. + +.. activecode:: ac_l50_4b_en + :nocodelens: + :language: python3 + :python3_interpreter: brython + + from browser import document, html, bind + from browser.widgets.dialog import Dialog + + + def create_element(audio_url, audio_name): + print(f"Creating the audio element {audio_url}") + document <= html.AUDIO(id=audio_name, src=audio_url) + + + def start_audio(element): + document[element].play() + + + def pause_audio(element): + document[element].pause() + + + correct = incorrect = 0 + + # Correct sound + create_element("http://www.superluigibros.com/downloads/sounds/SNES/SMRPG/wav/smrpg_correct.wav", "correct") + # Incorrect sound + create_element("https://bigsoundbank.com/UPLOAD/ogg/1684.ogg", "incorrect") + + d = Dialog("Zombies Question Show", top=20, left=20) + + d.panel <= html.H4( + "Press the buttons", id="window_title", style=dict(textAlign="center") + ) + d.panel <= html.SPAN( + str(correct), id="correct_counter", style=dict(paddingRight="2em") + ) + html.BUTTON("Correct", id="btn_correct") + d.panel <= html.BUTTON( + "Incorrect", id="btn_incorrect", style=dict(marginLeft="5em") + ) + html.SPAN( + str(incorrect), id="incorrect_counter", style=dict(paddingLeft="2em") + ) + + + @bind(document["btn_correct"], "click") + def press_correct_button(ev): + global correct + start_audio("correct") + correct += 1 + document["correct_counter"].textContent = str(correct) + print("You pressed the correct button") + + + @bind(document["btn_incorrect"], "click") + def press_incorrect_button(ev): + global incorrect + start_audio("incorrect") + incorrect += 1 + document["incorrect_counter"].textContent = str(incorrect) + print("You pressed the incorrect button") + ++ Great! Everything works perfectly. ++ You can change the audio for each option. ++ The boss is happy with the Zombies Question Show. + +.. image:: ../img/TWP50_017.jpg + :height: 14.861cm + :width: 15.801cm + :align: center + :alt: + + +Remember +-------- + ++ Use of the functionalities with the ``brython`` component. ++ It is not the only way to create graphical interfaces. + + Use of third-party library: ``pygame`` and ``tkinter``. ++ To handle events, an event controller is used. + + Event controller: function that is executed when the event occurs. \ No newline at end of file diff --git a/293/_sources/lectures/TWP50/toctree.rst.txt b/293/_sources/lectures/TWP50/toctree.rst.txt new file mode 100644 index 0000000000..040fcce9c9 --- /dev/null +++ b/293/_sources/lectures/TWP50/toctree.rst.txt @@ -0,0 +1,21 @@ +================ +Interfaz gráfica +================ + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP50_1.rst + TWP50_2.rst + TWP50_3.rst + TWP50_4.rst diff --git a/293/_sources/lectures/TWP50/toctree_en.rst.txt b/293/_sources/lectures/TWP50/toctree_en.rst.txt new file mode 100644 index 0000000000..aa7c677f78 --- /dev/null +++ b/293/_sources/lectures/TWP50/toctree_en.rst.txt @@ -0,0 +1,21 @@ +======================== +Graphical User Interface +======================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP50_1_en.rst + TWP50_2_en.rst + TWP50_3_en.rst + TWP50_4_en.rst diff --git a/293/_sources/lectures/TWP52.rst.txt b/293/_sources/lectures/TWP52.rst.txt new file mode 100644 index 0000000000..7e3e88b6ad --- /dev/null +++ b/293/_sources/lectures/TWP52.rst.txt @@ -0,0 +1,274 @@ +=== +MVC +=== + + +.. image:: img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + + +HEAD-Ex Logística y Transporte +============================== + + + +.. image:: img/TWP52_001.jpg + :height: 11.207cm + :width: 15.193cm + :align: center + :alt: + + + +HEAD-Ex Logística y Transporte +============================== + + +.. code-block :: python + + + def salvar_dados(): + fileD = open('encomendas.txt','a') + fileD.write('Destino: ') + fileD.write('%s\n' %destino.get()) + fileD.write('Descripcion: ') + fileD.write('%s\n' %descricao.get()) + fileD.write('Habla a: ') + fileD.write('%s\n' %endereco.get('1.0',END)) + destino.delete(0,END) + descricao.delete(0,END) + endereco.delete('1.0',END) + + + +HEAD-Ex Logística y Transporte +============================== + + +.. code-block :: python + + from tkinter import * + + app = Tk() + app.title('HEAD-Ex Logística y Transporte') + app.geometry("250x180+200+100") + + Label(app,text = "Destino: ").pack() + destino = Entry(app) + destino.pack() + + Label(app,text = "Descripcion: ").pack() + descricao = Entry(app) + descricao.pack() + + Label(app,text = "Habla a: ").pack() + endereco = Entry(app) + endereco.pack() + + Button(app, text = "Salvar" , command = salvar_dados).pack() + app.mainloop() + + +HEAD-Ex Logística e Transporte +============================== + + +.. image:: img/TWP52_005.jpg + :height: 12.571cm + :width: 19.302cm + :align: center + :alt: + + +HEAD-Ex Logística y Transporte +============================== + + +.. image:: img/TWP52_006.jpg + :height: 15.565cm + :width: 17.401cm + :align: center + :alt: + + +HEAD-Ex Logística y Transporte +============================== + ++ Radio Buttons + + +.. image:: img/TWP52_007.png + :height: 13.973cm + :width: 15.801cm + :align: center + :alt: + + +HEAD-Ex Logística y Transporte +============================== + + +.. image:: img/TWP52_008.jpg + :height: 8.254cm + :width: 7.831cm + :align: center + :alt: + + +HEAD-Ex Logística y Transporte +============================== + + +.. image:: img/TWP52_009.jpg + :height: 12.571cm + :width: 15.212cm + :align: center + :alt: + + +HEAD-Ex Logística y Transporte +============================== + + +.. image:: img/TWP52_013.jpg + :height: 9.048cm + :width: 18.123cm + :align: center + :alt: + + +HEAD-Ex Logística y Transporte +============================== + +.. image:: img/TWP52_014.png + :height: 4.176cm + :width: 13cm + :align: center + :alt: + ++ Modelo son los datos almacenados ++ Vision es el botón de radio presentado ++ Control es el código tkinter que gestiona todo esto + +.. code-block :: python + + Label(app, text = 'Destino: ').pack() + destino = StringVar() + destino.set(None) + Radiobutton(app, variable = destino , text = 'Cambridge , MA', value = 'Cambridge , MA').pack() + Radiobutton(app, variable = destino , text = 'Cambridge , UK', value = 'Cambridge , UK').pack() + Radiobutton(app, variable = destino , text = 'Seattle, WA', value = 'Seattle , WA').pack() + + +HEAD-Ex Logística e Transporte +============================== + + +.. image:: img/TWP52_016.jpg + :height: 14.578cm + :width: 20.401cm + :align: center + :alt: + + +HEAD-Ex Logística e Transporte +============================== + + +.. image:: img/TWP52_017.png + :height: 12.571cm + :width: 18.208cm + :align: center + :alt: + ++ Y ahora?? + + +HEAD-Ex Logística e Transporte +============================== + + +.. code-block :: python + + + def salvar_dados(): + fileD = open('encomendas.txt','a') + fileD.write('Destino: ') + fileD.write('%s\n' %destino.get()) + fileD.write('Descricao: ') + fileD.write('%s\n' %descricao.get()) + fileD.write('Endereco: ') + fileD.write('%s\n' %endereco.get('1.0',END)) + destino.delete(0,END) + descricao.delete(0,END) + endereco.delete('1.0',END) + + def ler_destinos(archivo): + destinos = [] + f = open(archivo) + for linha in f: + destinos.append(linha.rstrip()) + return destinos + + +HEAD-Ex Logística e Transporte +============================== + + +.. code-block :: python + + from tkinter import * + + app = Tk() + app.title('HEAD-Ex Logística e Transporte') + Label(app,text = "Destino: ").pack() + destino = StringVar() + destino.set(None) + + opcoes = ler_destinos("cidades.txt") + OptionMenu(app,destino,*opcoes).pack() + + Label(app,text = "Descripcion: ").pack() + descricao = Entry(app) + descricao.pack() + Label(app,text = "Habla a: ").pack() + endereco = Entry(app) + endereco.pack() + Button(app, text = "Ahorrar" , command = salvar_dados).pack() + app.mainloop() + + + +HEAD-Ex Logística y Transporte +============================== + + +.. image:: img/TWP52_020.jpg + :height: 12.571cm + :width: 17.025cm + :align: center + :alt: + + +revisión +======== + + + ++ MVC - Modelo, Visión, Control ++ Entry() ++ Texto() ++ StringVar() ++ RadioButton() ++ OptionMenu() + + + + +.. disqus:: + :shortname: pyzombis + :identifier: lecture19 diff --git a/293/_sources/lectures/TWP52_en.rst.txt b/293/_sources/lectures/TWP52_en.rst.txt new file mode 100644 index 0000000000..0e84891a09 --- /dev/null +++ b/293/_sources/lectures/TWP52_en.rst.txt @@ -0,0 +1,273 @@ +=== +MVC +=== + + +.. image:: img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + + +HEAD-Ex Logistics and Transportation +==================================== + + + +.. image:: img/TWP52_001.jpg + :height: 11.207cm + :width: 15.193cm + :align: center + :alt: + + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. code-block :: python + + + def salvar_dados(): + fileD = open('encomendas.txt','a') + fileD.write('Destino: ') + fileD.write('%s\n' %destino.get()) + fileD.write('Descripcion: ') + fileD.write('%s\n' %descricao.get()) + fileD.write('Habla a: ') + fileD.write('%s\n' %endereco.get('1.0',END)) + destino.delete(0,END) + descricao.delete(0,END) + endereco.delete('1.0',END) + + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. code-block :: python + + from tkinter import * + + app = Tk() + app.title('HEAD-Ex Logística y Transporte') + app.geometry("250x180+200+100") + + Label(app,text = "Destino: ").pack() + destino = Entry(app) + destino.pack() + + Label(app,text = "Descripcion: ").pack() + descricao = Entry(app) + descricao.pack() + + Label(app,text = "Habla a: ").pack() + endereco = Entry(app) + endereco.pack() + + Button(app, text = "Salvar" , command = salvar_dados).pack() + app.mainloop() + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. image:: img/TWP52_005.jpg + :height: 12.571cm + :width: 19.302cm + :align: center + :alt: + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. image:: img/TWP52_006.jpg + :height: 15.565cm + :width: 17.401cm + :align: center + :alt: + + +HEAD-Ex Logistics and Transportation +==================================== + ++ Radio Buttons + + +.. image:: img/TWP52_007.png + :height: 13.973cm + :width: 15.801cm + :align: center + :alt: + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. image:: img/TWP52_008.jpg + :height: 8.254cm + :width: 7.831cm + :align: center + :alt: + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. image:: img/TWP52_009.jpg + :height: 12.571cm + :width: 15.212cm + :align: center + :alt: + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. image:: img/TWP52_013.jpg + :height: 9.048cm + :width: 18.123cm + :align: center + :alt: + + +HEAD-Ex Logistics and Transportation +==================================== + +.. image:: img/TWP52_014.png + :height: 4.176cm + :width: 13cm + :align: center + :alt: + ++ Model is the stored data ++ Vision is the featured radio button ++ Control is the tkinter code that manages all this + +.. code-block :: python + + Label(app, text = 'Destino: ').pack() + destino = StringVar() + destino.set(None) + Radiobutton(app, variable = destino , text = 'Cambridge , MA', value = 'Cambridge , MA').pack() + Radiobutton(app, variable = destino , text = 'Cambridge , UK', value = 'Cambridge , UK').pack() + Radiobutton(app, variable = destino , text = 'Seattle, WA', value = 'Seattle , WA').pack() + + +HEAD-Ex Logistics and Transportation +==================================== + +.. image:: img/TWP52_016.jpg + :height: 14.578cm + :width: 20.401cm + :align: center + :alt: + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. image:: img/TWP52_017.png + :height: 12.571cm + :width: 18.208cm + :align: center + :alt: + ++ And now?? + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. code-block :: python + + + def salvar_dados(): + fileD = open('encomendas.txt','a') + fileD.write('Destino: ') + fileD.write('%s\n' %destino.get()) + fileD.write('Descricao: ') + fileD.write('%s\n' %descricao.get()) + fileD.write('Endereco: ') + fileD.write('%s\n' %endereco.get('1.0',END)) + destino.delete(0,END) + descricao.delete(0,END) + endereco.delete('1.0',END) + + def ler_destinos(archivo): + destinos = [] + f = open(archivo) + for linha in f: + destinos.append(linha.rstrip()) + return destinos + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. code-block :: python + + from tkinter import * + + app = Tk() + app.title('HEAD-Ex Logística e Transporte') + Label(app,text = "Destino: ").pack() + destino = StringVar() + destino.set(None) + + opcoes = ler_destinos("cidades.txt") + OptionMenu(app,destino,*opcoes).pack() + + Label(app,text = "Descripcion: ").pack() + descricao = Entry(app) + descricao.pack() + Label(app,text = "Habla a: ").pack() + endereco = Entry(app) + endereco.pack() + Button(app, text = "Ahorrar" , command = salvar_dados).pack() + app.mainloop() + + + +HEAD-Ex Logistics and Transportation +==================================== + + +.. image:: img/TWP52_020.jpg + :height: 12.571cm + :width: 17.025cm + :align: center + :alt: + + +review +====== + + + ++ MVC - Model, Visión, Control ++ Entry() ++ Texto() ++ StringVar() ++ RadioButton() ++ OptionMenu() + + + + +.. disqus:: + :shortname: pyzombis + :identifier: lecture19 diff --git a/293/_sources/lectures/TWP54/TWP54_1.rst.txt b/293/_sources/lectures/TWP54/TWP54_1.rst.txt new file mode 100644 index 0000000000..5804e73a4c --- /dev/null +++ b/293/_sources/lectures/TWP54/TWP54_1.rst.txt @@ -0,0 +1,33 @@ +Introducción a las excepciones +============================== + +.. image:: ../img/TWP54_001.jpg + :height: 14.249cm + :width: 17.401cm + :align: center + :alt: + + ++ A veces las cosas salen mal. Y necesitas tratarlas. + ++ Siempre hay cosas que están fuera de tu control. Las redes fallan. + Los archivos desaparecen. + ++ Los códigos inteligentes aprenden a lidiar con estos errores y hacen que + programa para recuperarse sin problemas. + + +¡Qué mal olor! +-------------- + +.. image:: ../img/TWP54_002.jpg + :height: 14.477cm + :width: 12.6cm + :align: center + :alt: + +.. image:: ../img/TWP54_003.jpg + :height: 14.219cm + :width: 20.601cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP54/TWP54_1_en.rst.txt b/293/_sources/lectures/TWP54/TWP54_1_en.rst.txt new file mode 100644 index 0000000000..f13b0633a9 --- /dev/null +++ b/293/_sources/lectures/TWP54/TWP54_1_en.rst.txt @@ -0,0 +1,31 @@ +Introduction to Exceptions +============================== + +.. image:: ../img/TWP54_001.jpg + :height: 14.249cm + :width: 17.401cm + :align: center + :alt: + ++ Sometimes things go wrong. And you need to handle them. + ++ There are always things that are out of your control. Networks fail. + Files disappear. + ++ Smart codes learn to deal with these errors and make the program to + recover smoothly. + +That Stinks! +-------------- + +.. image:: ../img/TWP54_002.jpg + :height: 14.477cm + :width: 12.6cm + :align: center + :alt: + +.. image:: ../img/TWP54_003.jpg + :height: 14.219cm + :width: 20.601cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP54/TWP54_2.rst.txt b/293/_sources/lectures/TWP54/TWP54_2.rst.txt new file mode 100644 index 0000000000..ff74dc7d14 --- /dev/null +++ b/293/_sources/lectures/TWP54/TWP54_2.rst.txt @@ -0,0 +1,50 @@ +Se lanza una excepción +====================== + +.. image:: ../img/TWP54_004.jpg + :height: 11.211cm + :width: 22.859cm + :align: center + :alt: + + +Atrapando la excepción +---------------------- + +.. image:: ../img/TWP54_005.jpg + :height: 14.432cm + :width: 22.771cm + :align: center + :alt: + + +Manejo de excepciones +--------------------- + +.. code-block :: python + + def salvar_dados(): + try: + fileD = open("encomendas.txt","a") + fileD.write("Destino:\n") + fileD.write("%s\n" %destino.get()) + fileD.write("Descripcion:\n") + fileD.write("%s\n" %descripcion.get()) + fileD.write("Habla:\n") + fileD.write("%s\n" %Habla.get("1.0",END)) + destino.set(None) + descricao.delete(0,END) + endereco.delete("1.0",END) + except Excepción como excepciones: + app.title('archivo de grabación %s' %excepcion) + + + ++ Obs.: para você testar a exceção deverá alterar as propriedades do arquivo + + +.. image:: ../img/TWP54_007.jpg + :height: 7.611cm + :width: 22.859cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP54/TWP54_2_en.rst.txt b/293/_sources/lectures/TWP54/TWP54_2_en.rst.txt new file mode 100644 index 0000000000..dbc2705035 --- /dev/null +++ b/293/_sources/lectures/TWP54/TWP54_2_en.rst.txt @@ -0,0 +1,50 @@ +Raising an Exception +====================== + +.. image:: ../img/TWP54_004.jpg + :height: 11.211cm + :width: 22.859cm + :align: center + :alt: + + +Catching the Exception +---------------------- + +.. image:: ../img/TWP54_005.jpg + :height: 14.432cm + :width: 22.771cm + :align: center + :alt: + + +Handling Exceptions +--------------------- + +.. code-block :: python + + def save_data(): + try: + fileD = open("orders.txt","a") + fileD.write("Destination:\n") + fileD.write("%s\n" %destination.get()) + fileD.write("Description:\n") + fileD.write("%s\n" %description.get()) + fileD.write("Speech:\n") + fileD.write("%s\n" %Speech.get("1.0",END)) + destination.set(None) + description.delete(0,END) + address.delete("1.0",END) + except Exception as exception: + app.title('Recording file %s' %exception) + + + ++ Note: to test the exception you will need to change the properties of the file + + +.. image:: ../img/TWP54_007.jpg + :height: 7.611cm + :width: 22.859cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP54/TWP54_3.rst.txt b/293/_sources/lectures/TWP54/TWP54_3.rst.txt new file mode 100644 index 0000000000..3ea13373a6 --- /dev/null +++ b/293/_sources/lectures/TWP54/TWP54_3.rst.txt @@ -0,0 +1,33 @@ +Usando un messagebox +==================== + +.. code-block :: python + + def salvar_dados(): + try: + fileD = open("encomendas.txt","a") + fileD.write("Destino:\n") + fileD.write("%s\n" %destino.get()) + fileD.write("Descricao:\n") + fileD.write("%s\n" %descricao.get()) + fileD.write("Endereco:\n") + fileD.write("%s\n" %endereco.get("1.0",END)) + destino.set(None) + descricao.delete(0,END) + endereco.delete("1.0",END) + except Exception as excecao: + app.title('Erro de gravacao no arquivo %s' %excecao) + + +.. image:: ../img/TWP54_009.jpg + :height: 8.042cm + :width: 18.335cm + :align: center + :alt: + + +.. image:: ../img/TWP54_010.jpg + :height: 15.573cm + :width: 13.348cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP54/TWP54_3_en.rst.txt b/293/_sources/lectures/TWP54/TWP54_3_en.rst.txt new file mode 100644 index 0000000000..6d9f961992 --- /dev/null +++ b/293/_sources/lectures/TWP54/TWP54_3_en.rst.txt @@ -0,0 +1,33 @@ +Using a messagebox +==================== + +.. code-block:: python + + def save_data(): + try: + fileD = open("orders.txt","a") + fileD.write("Destination:\n") + fileD.write("%s\n" %destination.get()) + fileD.write("Description:\n") + fileD.write("%s\n" %description.get()) + fileD.write("Address:\n") + fileD.write("%s\n" %address.get("1.0",END)) + destination.set(None) + description.delete(0,END) + address.delete("1.0",END) + except Exception as exception: + app.title('File writing error: %s' %exception) + + +.. image:: ../img/TWP54_009.jpg + :height: 8.042cm + :width: 18.335cm + :align: center + :alt: + + +.. image:: ../img/TWP54_010.jpg + :height: 15.573cm + :width: 13.348cm + :align: center + :alt: \ No newline at end of file diff --git a/293/_sources/lectures/TWP54/toctree.rst.txt b/293/_sources/lectures/TWP54/toctree.rst.txt new file mode 100644 index 0000000000..6244b5012b --- /dev/null +++ b/293/_sources/lectures/TWP54/toctree.rst.txt @@ -0,0 +1,20 @@ +=========== +Excepciones +=========== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP54_1.rst + TWP54_2.rst + TWP54_3.rst diff --git a/293/_sources/lectures/TWP54/toctree_en.rst.txt b/293/_sources/lectures/TWP54/toctree_en.rst.txt new file mode 100644 index 0000000000..5d393ea089 --- /dev/null +++ b/293/_sources/lectures/TWP54/toctree_en.rst.txt @@ -0,0 +1,20 @@ +========== +Exceptions +========== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP54_1_en.rst + TWP54_2_en.rst + TWP54_3_en.rst diff --git a/293/_sources/lectures/TWP56/TWP56_1.rst.txt b/293/_sources/lectures/TWP56/TWP56_1.rst.txt new file mode 100644 index 0000000000..4d9feee304 --- /dev/null +++ b/293/_sources/lectures/TWP56/TWP56_1.rst.txt @@ -0,0 +1,35 @@ +DJ Mix +====== + + +.. image:: ../img/TWP56_001.jpg + :height: 12.571cm + :width: 14.997cm + :align: center + :alt: + + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + som = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def start(): + track.play(loops = -1) + def stop(): + track.stop() + + track = mixer.Sound(som) + start_botao = Button(app, command = start, text = 'Start') + start_botao.pack(side = LEFT) + stop_botao = Button(app, command = stop, text = 'Stop') + stop_botao.pack(side = RIGHT) + app.mainloop() diff --git a/293/_sources/lectures/TWP56/TWP56_1_en.rst.txt b/293/_sources/lectures/TWP56/TWP56_1_en.rst.txt new file mode 100644 index 0000000000..069acb665a --- /dev/null +++ b/293/_sources/lectures/TWP56/TWP56_1_en.rst.txt @@ -0,0 +1,36 @@ +DJ Mix +====== + + +.. image:: ../img/TWP56_001.jpg + :height: 12.571cm + :width: 14.997cm + :align: center + :alt: + + +.. code-block:: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + som = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def start(): + track.play(loops=-1) + + def stop(): + track.stop() + + track = mixer.Sound(som) + start_button = Button(app, command=start, text='Start') + start_button.pack(side=LEFT) + stop_button = Button(app, command=stop, text='Stop') + stop_button.pack(side=RIGHT) + app.mainloop() \ No newline at end of file diff --git a/293/_sources/lectures/TWP56/TWP56_2.rst.txt b/293/_sources/lectures/TWP56/TWP56_2.rst.txt new file mode 100644 index 0000000000..67ef229f7c --- /dev/null +++ b/293/_sources/lectures/TWP56/TWP56_2.rst.txt @@ -0,0 +1,81 @@ +Pero la canción no termina... +============================= + + +.. image:: ../img/TWP56_003.jpg + :height: 12.571cm + :width: 19.957cm + :align: center + :alt: + + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + som = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def start(): + track.play(loops = -1) + def stop(): + track.stop() + def termina(): + track.stop() + app.destroy() + + track = mixer.Sound(som) + start_botao = Button(app, command = start, text = 'Start') + start_botao.pack(side = LEFT) + stop_botao = Button(app, command = stop, text = 'Stop') + stop_botao.pack(side = RIGHT) + + app.protocol('WM_DELETE_WINDOW',terminal) + app.mainloop() + + +Un solo botón +------------- + +.. image:: ../img/TWP56_005.jpg + :height: 15.578cm + :width: 12.183cm + :align: center + :alt: + + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + som = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def termina(): + track.stop() + app.destroy() + def muda(): + if tocando.get() == 1: + track.play(loops = -1) + else: + track.stop() + + track = mixer.Sound(som) + tocando = IntVar() + tocar = Checkbutton(app,variable = tocando, command = muda, text = som) + tocar.pack() + + app.protocol('WM_DELETE_WINDOW',terminal) + app.mainloop() diff --git a/293/_sources/lectures/TWP56/TWP56_2_en.rst.txt b/293/_sources/lectures/TWP56/TWP56_2_en.rst.txt new file mode 100644 index 0000000000..218406535c --- /dev/null +++ b/293/_sources/lectures/TWP56/TWP56_2_en.rst.txt @@ -0,0 +1,80 @@ +But the song never ends... +=========================== + +.. image:: ../img/TWP56_003.jpg + :height: 12.571cm + :width: 19.957cm + :align: center + :alt: + + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + sound = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def start(): + track.play(loops = -1) + def stop(): + track.stop() + def terminate(): + track.stop() + app.destroy() + + track = mixer.Sound(sound) + start_button = Button(app, command = start, text = 'Start') + start_button.pack(side = LEFT) + stop_button = Button(app, command = stop, text = 'Stop') + stop_button.pack(side = RIGHT) + + app.protocol('WM_DELETE_WINDOW',terminate) + app.mainloop() + + +One button only +--------------- + +.. image:: ../img/TWP56_005.jpg + :height: 15.578cm + :width: 12.183cm + :align: center + :alt: + + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + sound = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def terminate(): + track.stop() + app.destroy() + def switch(): + if playing.get() == 1: + track.play(loops = -1) + else: + track.stop() + + track = mixer.Sound(sound) + playing = IntVar() + play_button = Checkbutton(app, variable = playing, command = switch, text = sound) + play_button.pack() + + app.protocol('WM_DELETE_WINDOW',terminate) + app.mainloop() \ No newline at end of file diff --git a/293/_sources/lectures/TWP56/TWP56_3.rst.txt b/293/_sources/lectures/TWP56/TWP56_3.rst.txt new file mode 100644 index 0000000000..52885c6434 --- /dev/null +++ b/293/_sources/lectures/TWP56/TWP56_3.rst.txt @@ -0,0 +1,61 @@ +Se ve genial, ¡ahora agreguemos un volumen! +=========================================== + +.. image:: ../img/TWP56_008.jpg + :height: 11.357cm + :width: 12cm + :align: center + :alt: + + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + som = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def termina(): + track.stop() + app.destroy() + def muda(): + if tocando.get() == 1: + track.play(loops = -1) + else: + track.stop() + def muda_volume(v): + track.set_volume(volume.get()) + + track = mixer.Sound(som) + tocando = IntVar() + tocar = Checkbutton(app,variable = tocando, command = muda, text = som) + tocar.pack(side = LEFT) + volume = DoubleVar() + volume.set(track.get_volume()) + escala = Scale(variable = volume , from = 0.0 , to = 1.0 , resolution = 0.1, command = muda_volume, label = 'Volume',orient = HORIZONTAL) + + escala.pack(side = RIGHT) + app.protocol('WM_DELETE_WINDOW',terminal) + app.mainloop() + + +.. image:: ../img/TWP56_010.jpg + :height: 15.024cm + :width: 19.401cm + :align: center + :alt: + + +Recuerda +-------- + ++ app.destroy() ++ DoubleVar() ++ Checkbutton() ++ Scale() diff --git a/293/_sources/lectures/TWP56/TWP56_3_en.rst.txt b/293/_sources/lectures/TWP56/TWP56_3_en.rst.txt new file mode 100644 index 0000000000..1015729af8 --- /dev/null +++ b/293/_sources/lectures/TWP56/TWP56_3_en.rst.txt @@ -0,0 +1,61 @@ +It looks great, now let's add some volume! +=========================================== + +.. image:: ../img/TWP56_008.jpg + :height: 11.357cm + :width: 12cm + :align: center + :alt: + + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + app = Tk() + app.title('DJ Mix') + app.geometry('250x100+200+100') + + som = '50459_M_RED_Nephlimizer.wav' + mixer = pygame.mixer + mixer.init() + + def terminate(): + track.stop() + app.destroy() + def toggle_play(): + if playing.get() == 1: + track.play(loops = -1) + else: + track.stop() + def change_volume(v): + track.set_volume(volume.get()) + + track = mixer.Sound(som) + playing = IntVar() + toggle = Checkbutton(app, variable=playing, command=toggle_play, text=som) + toggle.pack(side=LEFT) + volume = DoubleVar() + volume.set(track.get_volume()) + scale = Scale(variable=volume, from_=0.0, to=1.0, resolution=0.1, command=change_volume, label='Volume', orient=HORIZONTAL) + + scale.pack(side=RIGHT) + app.protocol('WM_DELETE_WINDOW', terminate) + app.mainloop() + + +.. image:: ../img/TWP56_010.jpg + :height: 15.024cm + :width: 19.401cm + :align: center + :alt: + + +Remember +-------- + ++ app.destroy() ++ DoubleVar() ++ Checkbutton() ++ Scale() \ No newline at end of file diff --git a/293/_sources/lectures/TWP56/toctree.rst.txt b/293/_sources/lectures/TWP56/toctree.rst.txt new file mode 100644 index 0000000000..24ee7891a9 --- /dev/null +++ b/293/_sources/lectures/TWP56/toctree.rst.txt @@ -0,0 +1,20 @@ +======== +DJ Mix 1 +======== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP56_1.rst + TWP56_2.rst + TWP56_3.rst diff --git a/293/_sources/lectures/TWP56/toctree_en.rst.txt b/293/_sources/lectures/TWP56/toctree_en.rst.txt new file mode 100644 index 0000000000..f5fbb0b9c9 --- /dev/null +++ b/293/_sources/lectures/TWP56/toctree_en.rst.txt @@ -0,0 +1,20 @@ +======== +DJ Mix 1 +======== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP56_1_en.rst + TWP56_2_en.rst + TWP56_3_en.rst diff --git a/293/_sources/lectures/TWP58/TWP58_1.rst.txt b/293/_sources/lectures/TWP58/TWP58_1.rst.txt new file mode 100644 index 0000000000..234fab5d32 --- /dev/null +++ b/293/_sources/lectures/TWP58/TWP58_1.rst.txt @@ -0,0 +1,39 @@ +POO - Programación Orientada a Objetos +====================================== + +.. image:: ../img/TWP58_002.jpeg + :height: 4.629cm + :width: 13.81cm + :align: center + :alt: + + ++ Tenemos DJ Mix para una canción ++ Ahora necesitamos varios ++ KISS – Kept It Simple Stupid ++ ¡No duplicaremos el código! + + +.. image:: ../img/TWP58_003.jpg + :height: 13.704cm + :width: 9.736cm + :align: center + :alt: + + +Vamos a juntar todos los objetos en un Frame +-------------------------------------------- + + +.. image:: ../img/TWP58_004.jpg + :height: 10.966cm + :width: 22.859cm + :align: center + :alt: + + +.. image:: ../img/TWP58_005.jpg + :height: 14.21cm + :width: 13.435cm + :align: center + :alt: diff --git a/293/_sources/lectures/TWP58/TWP58_1_en.rst.txt b/293/_sources/lectures/TWP58/TWP58_1_en.rst.txt new file mode 100644 index 0000000000..e7fec2b741 --- /dev/null +++ b/293/_sources/lectures/TWP58/TWP58_1_en.rst.txt @@ -0,0 +1,39 @@ +POO - Object Oriented Programming +================================== + +.. image:: ../img/TWP58_002.jpeg + :height: 4.629cm + :width: 13.81cm + :align: center + :alt: + ++ We have a DJ Mix for a song ++ Now we need several ++ KISS - Keep It Simple Stupid ++ We will not duplicate the code! + + +.. image:: ../img/TWP58_003.jpg + :height: 13.704cm + :width: 9.736cm + :align: center + :alt: + +Let's put all the objects together in a Frame +---------------------------------------------- + +.. image:: ../img/TWP58_004.jpg + :height: 10.966cm + :width: 22.859cm + :align: center + :alt: + +.. image:: ../img/TWP58_005.jpg + :height: 14.21cm + :width: 13.435cm + :align: center + :alt: + +Python code: + +We do not have any Python code in this section. \ No newline at end of file diff --git a/293/_sources/lectures/TWP58/TWP58_2.rst.txt b/293/_sources/lectures/TWP58/TWP58_2.rst.txt new file mode 100644 index 0000000000..f618023471 --- /dev/null +++ b/293/_sources/lectures/TWP58/TWP58_2.rst.txt @@ -0,0 +1,101 @@ +Clase = fábrica de objetos +========================== + + +.. image:: ../img/TWP58_006.jpg + :height: 12.514cm + :width: 22.7cm + :align: center + :alt: + + +.. image:: ../img/TWP58_007.jpg + :height: 9.471cm + :width: 22.647cm + :align: center + :alt: + + +Clase SoundPanel +---------------- + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + class SoundPanel(Frame): + def track_toggle(self): + if self.track_playing.get() == 1: + self.track.play(loops = -1) + else: + self.track.stop() + def change_volume(self,v): + self.track.set_volume(self.volume.get()) + def __init__(self,app,mixer,sound_file): + Frame.__init__(self,app) + self.track = mixer.Sound(sound_file) + self.track_playing = IntVar() + track_button = Checkbutton(self,variable = self.track_playing,command = self.track_toggle,text = sound_file) + track_button.pack(side = LEFT) + self.volume = DoubleVar() + self.volume.set(self.track.get_volume()) + volume_scale = Scale(self,variable = self.volume, from_ = 0.0, to = 1.0, resolution = 0.1, command = self.change_volume, label = "Volume", orient = HORIZONTAL) + volume_scale.pack(side = RIGHT) + + +Programa principal +------------------ + +.. code-block :: python + + from tkinter import * + from sound_panel import * + import pygame.mixer + import os + + app = Tk() + app.title("Head First Mix") + + mixer = pygame.mixer + mixer.init() + + dirList = os.listdir(".") + for fname in dirList: + if fname.endswith(".wav") and fname[0] in '345': + SoundPanel(app,mixer,fname).pack() + + def shutdown(): + mixer.stop() + app.destroy() + + app.protocol("WM_DELETE_WINDOW",shutdown) + app.mainloop() + + ++ ¡Felicidades! Ahora sabes cómo crear programas complejos con poco código. + + +.. image:: ../img/TWP58_010.png + :height: 14.125cm + :width: 19.746cm + :align: center + :alt: + + +.. image:: ../img/TWP58_011.png + :height: 5.45cm + :width: 3.91cm + :align: center + :alt: + + +Recuerda +-------- + ++ Las clases son fábricas de objetos ++ Classe = métodos + datos ++ Crear objetos = instanciar una clase ++ class – comienza la definición de una clase ++ self – autoasignado al objeto actual ++ __init__() Se llama al crear el objeto diff --git a/293/_sources/lectures/TWP58/TWP58_2_en.rst.txt b/293/_sources/lectures/TWP58/TWP58_2_en.rst.txt new file mode 100644 index 0000000000..0749d9c13d --- /dev/null +++ b/293/_sources/lectures/TWP58/TWP58_2_en.rst.txt @@ -0,0 +1,101 @@ +Class = object factory +========================== + + +.. image:: ../img/TWP58_006.jpg + :height: 12.514cm + :width: 22.7cm + :align: center + :alt: + + +.. image:: ../img/TWP58_007.jpg + :height: 9.471cm + :width: 22.647cm + :align: center + :alt: + + +Class SoundPanel +---------------- + +.. code-block :: python + + from tkinter import * + import pygame.mixer + + class SoundPanel(Frame): + def track_toggle(self): + if self.track_playing.get() == 1: + self.track.play(loops = -1) + else: + self.track.stop() + def change_volume(self,v): + self.track.set_volume(self.volume.get()) + def __init__(self,app,mixer,sound_file): + Frame.__init__(self,app) + self.track = mixer.Sound(sound_file) + self.track_playing = IntVar() + track_button = Checkbutton(self,variable = self.track_playing,command = self.track_toggle,text = sound_file) + track_button.pack(side = LEFT) + self.volume = DoubleVar() + self.volume.set(self.track.get_volume()) + volume_scale = Scale(self,variable = self.volume, from_ = 0.0, to = 1.0, resolution = 0.1, command = self.change_volume, label = "Volume", orient = HORIZONTAL) + volume_scale.pack(side = RIGHT) + + +Main program +------------------ + +.. code-block :: python + + from tkinter import * + from sound_panel import * + import pygame.mixer + import os + + app = Tk() + app.title("Head First Mix") + + mixer = pygame.mixer + mixer.init() + + dirList = os.listdir(".") + for fname in dirList: + if fname.endswith(".wav") and fname[0] in '345': + SoundPanel(app,mixer,fname).pack() + + def shutdown(): + mixer.stop() + app.destroy() + + app.protocol("WM_DELETE_WINDOW",shutdown) + app.mainloop() + + ++ Congratulations! Now you know how to create complex programs with little code. + + +.. image:: ../img/TWP58_010.png + :height: 14.125cm + :width: 19.746cm + :align: center + :alt: + + +.. image:: ../img/TWP58_011.png + :height: 5.45cm + :width: 3.91cm + :align: center + :alt: + + +Remember +-------- + ++ Classes are object factories ++ Class = methods + data ++ Create objects = instantiate a class ++ class - begins the definition of a class ++ self - assigned to the current object ++ __init__() - called when the object is created \ No newline at end of file diff --git a/293/_sources/lectures/TWP58/toctree.rst.txt b/293/_sources/lectures/TWP58/toctree.rst.txt new file mode 100644 index 0000000000..65c88308f3 --- /dev/null +++ b/293/_sources/lectures/TWP58/toctree.rst.txt @@ -0,0 +1,19 @@ +===================================== +DJ Mix 2 revisión orientada a objetos +===================================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP58_1.rst + TWP58_2.rst diff --git a/293/_sources/lectures/TWP58/toctree_en.rst.txt b/293/_sources/lectures/TWP58/toctree_en.rst.txt new file mode 100644 index 0000000000..8fe9a47828 --- /dev/null +++ b/293/_sources/lectures/TWP58/toctree_en.rst.txt @@ -0,0 +1,19 @@ +===================================== +DJ Mix 2 revisión orientada a objetos +===================================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP58_1_en.rst + TWP58_2_en.rst diff --git a/293/_sources/lectures/TWP60/TWP60_1.rst.txt b/293/_sources/lectures/TWP60/TWP60_1.rst.txt new file mode 100644 index 0000000000..ace03f3ff1 --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_1.rst.txt @@ -0,0 +1,164 @@ +Pygame Hello World +================== + +Bibliografía +------------ + +.. image:: ../img/TWP60_001.jpeg + :height: 11.25cm + :width: 9cm + :align: center + :alt: + + ++ `Book Link `_ + + +.. image:: ../img/TWP60_002.jpeg + :height: 6cm + :width: 5.97cm + :align: center + :alt: + + + +Pygame Hello World +------------------ + +.. activecode:: ac_l60_1 + :language: python3 + :python3_interpreter: brython + + from browser import load + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + import pygame, sys + from pygame.locals import * + from pygame.color import * + #set up pygame + pygame.init() + + #set up the window + windowSurface = pygame.display.set_mode((500,400)) + + #set up the colors + BLACK = Color(0,0,0) + WHITE = Color(255,255,255) + RED = Color(255,0,0) + GREEN = Color(0,255,0) + BLUE = Color(0,0,255) + + #set up fonts + basicFont = pygame.font.SysFont('timesnewroman',30) + #set up the text + text = basicFont.render("Hello world!",False,BLACK,WHITE) + textRect = text.get_rect() + + textRect.centerx = windowSurface.get_rect().centerx + textRect.centery = windowSurface.get_rect().centery + + #draw the white background onto the surface + windowSurface.fill(WHITE) + + #draw a green polygon onto the surface + pygame.draw.polygon(windowSurface,GREEN,((146,0),(291,106),(236,277))) + + #draw some blue lies onto the surface + pygame.draw.line(windowSurface,BLUE,(60,60),(120,60),4) + pygame.draw.line(windowSurface,BLUE,(120,60),(60,120)) + pygame.draw.line(windowSurface,BLUE,(60,120),(120,120),4) + + #draw a blue circle onto the surface + pygame.draw.circle(windowSurface,BLUE,(300,50),20,0) + windowSurface.blit(text, textRect) + + + +.. code-block:: python + + import pygame, sys + from pygame.locals import * + + #set up pygame + pygame.init() + + #set up the window + windowSurface = pygame.display.set_mode((500,400),0,32) + pygame.display.set_caption('Hello world!') + + #set up the colors + BLACK = (0,0,0) + WHITE = (255,255,255) + RED = (255,0,0) + GREEN = (0,255,0) + BLUE = (0,0,255) + + #set up fonts + basicFont = pygame.font.SysFont(None,48) + + ++ pygame.locals incluiye constantes como QUIT o K_ESCAPE ++ Utilizamos sys.exit() para salir “suavemente” del programa + + +.. code-block :: python + + #set up the text + text = basicFont.render('Hello world!',True,WHITE,BLUE) + textRect = text.get_rect() + textRect.centerx = windowSurface.get_rect().centerx + textRect.centery = windowSurface.get_rect().centery + + #draw the white background onto the surface + windowSurface.fill(WHITE) + + #draw a green polygon onto the surface + pygame.draw.polygon(windowSurface,GREEN,((146,0),(291,106),(236,277))) + + #draw some blue lies onto the surface + pygame.draw.line(windowSurface,BLUE,(60,60),(120,60),4) + pygame.draw.line(windowSurface,BLUE,(120,60),(60,120)) + pygame.draw.line(windowSurface,BLUE,(60,120),(120,120),4) + + #draw a blue circle onto the surface + pygame.draw.circle(windowSurface,BLUE,(300,50),20,0) + + +.. image:: ../img/TWP60_005.png + :height: 9.727cm + :width: 10.2cm + :align: center + :alt: + + +.. code-block::python + + #get a pixel array of the surface + pixArray = pygame.PixelArray(windowSurface) + pixArray[480][380] = BLACK + del pixArray + + #draw the text onto the surface + windowSurface.blit(text, textRect) + + #draw the window onto the screen + pygame.display.update() + + #run the game loop + while True: + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + + + ++ Si no elimino pixArray, estará en estado bloqueado ++ Elimino pixArray para poder manejar el objeto Surface a través del método + blit () ++ El blit () solo modifica la memoria, pero para actualizar la pantalla debo + dar display.update () ++ No olvides dar pygame.quit () diff --git a/293/_sources/lectures/TWP60/TWP60_1_en.rst.txt b/293/_sources/lectures/TWP60/TWP60_1_en.rst.txt new file mode 100644 index 0000000000..7077da6e9a --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_1_en.rst.txt @@ -0,0 +1,151 @@ +Pygame Hello World +================== + +Bibliography +------------ + +.. image:: ../img/TWP60_001.jpeg + :height: 11.25cm + :width: 9cm + :align: center + :alt: + ++ `Book Link `_ + + +.. image:: ../img/TWP60_002.jpeg + :height: 6cm + :width: 5.97cm + :align: center + :alt: + +Pygame Hello World +------------------ + +.. activecode:: ac_l60_1_en + :language: python3 + :python3_interpreter: brython + + from browser import load + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + import pygame, sys + from pygame.locals import * + from pygame.color import * + + # set up pygame + pygame.init() + + # set up the window + windowSurface = pygame.display.set_mode((500,400)) + + # set up the colors + BLACK = Color(0,0,0) + WHITE = Color(255,255,255) + RED = Color(255,0,0) + GREEN = Color(0,255,0) + BLUE = Color(0,0,255) + + # set up fonts + basicFont = pygame.font.SysFont('timesnewroman',30) + + # set up the text + text = basicFont.render("Hello world!",False,BLACK,WHITE) + textRect = text.get_rect() + + textRect.centerx = windowSurface.get_rect().centerx + textRect.centery = windowSurface.get_rect().centery + + # draw the white background onto the surface + windowSurface.fill(WHITE) + + # draw a green polygon onto the surface + pygame.draw.polygon(windowSurface,GREEN,((146,0),(291,106),(236,277))) + + # draw some blue lines onto the surface + pygame.draw.line(windowSurface,BLUE,(60,60),(120,60),4) + pygame.draw.line(windowSurface,BLUE,(120,60),(60,120)) + pygame.draw.line(windowSurface,BLUE,(60,120),(120,120),4) + + # draw a blue circle onto the surface + pygame.draw.circle(windowSurface,BLUE,(300,50),20,0) + windowSurface.blit(text, textRect) + + +.. code-block:: python + + import pygame, sys + from pygame.locals import * + + # set up pygame + pygame.init() + + # set up the window + windowSurface = pygame.display.set_mode((500,400),0,32) + pygame.display.set_caption('Hello world!') + + # set up the colors + BLACK = (0,0,0) + WHITE = (255,255,255) + RED = (255,0,0) + GREEN = (0,255,0) + BLUE = (0,0,255) + + # set up fonts + basicFont = pygame.font.SysFont(None,48) + + # set up the text + text = basicFont.render('Hello world!',True,WHITE,BLUE) + textRect = text.get_rect() + textRect.centerx = windowSurface.get_rect().centerx + textRect.centery = windowSurface.get_rect().centery + + # draw the white background onto the surface + windowSurface.fill(WHITE) + + # draw a green polygon onto the surface + pygame.draw.polygon(windowSurface,GREEN,((146,0),(291,106),(236,277))) + + # draw some blue lines onto the surface + pygame.draw.line(windowSurface,BLUE,(60,60),(120,60),4) + pygame.draw.line(windowSurface,BLUE,(120,60),(60,120)) + pygame.draw.line(windowSurface,BLUE,(60,120),(120,120),4) + + # draw a blue circle onto the surface + pygame.draw.circle(windowSurface,BLUE,(300,50),20,0) + + +.. image:: ../img/TWP60_005.png + :height: 9.727cm + :width: 10.2cm + :align: center + :alt: + + +.. code-block:: python + + # get a pixel array of the surface + pixArray = pygame.PixelArray(windowSurface) + pixArray[480][380] = BLACK + del pixArray + + # draw the text onto the surface + windowSurface.blit(text, textRect) + + # draw the window onto the screen + pygame.display.update() + + # run the game loop + while True: + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + ++ If I don't delete pixArray, it will remain in a blocked state ++ I delete pixArray to be able to handle the Surface object through the blit() method ++ The blit() only modifies the memory, but to update the screen I must call display.update() ++ Don't forget to call pygame.quit() \ No newline at end of file diff --git a/293/_sources/lectures/TWP60/TWP60_2.rst.txt b/293/_sources/lectures/TWP60/TWP60_2.rst.txt new file mode 100644 index 0000000000..9c81a8bec7 --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_2.rst.txt @@ -0,0 +1,224 @@ +Pygame Animación +================ + + +.. image:: ../img/TWP60_007.png + :height: 11.826cm + :width: 11.217cm + :align: center + :alt: + + +.. image:: ../img/TWP60_008.png + :height: 11.747cm + :width: 10.503cm + :align: center + :alt: + + +.. activecode:: ac_l60_2 + :language: python3 + :python3_interpreter: brython + + from browser import load, document,timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + import pygame, sys , time + from pygame.locals import * + from pygame.color import * + + + #set up the colors + BLACK = Color(0,0,0) + WHITE = Color(255,255,255) + RED = Color(255,0,0) + GREEN = Color(0,255,0) + BLUE = Color(0,0,255) + # set up pygame + pygame.init() + + # set up the window + WINDOWWIDTH = 500 + WINDOWHEIGHT = 300 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + + # set up the direction variables + DOWNLEFT = 1 + DOWNRIGHT = 3 + UPLEFT = 7 + UPRIGHT = 9 + + MOVESPEED = 4 + + # set up the block data structure + b1 = {'rect':pygame.Rect(300,80,50,100),'color':RED,'dir':UPRIGHT} + b2 = {'rect':pygame.Rect(200,200,20,20),'color':BLUE,'dir':UPLEFT} + b3 = {'rect':pygame.Rect(100,150,60,60),'color':GREEN,'dir':DOWNLEFT} + blocks = [b1,b2,b3] + + def draw(): + # draw the black background onto the surface + windowSurface.fill(BLACK) + + for b in blocks: + # move the block data structure + if b['dir'] == DOWNLEFT: + b['rect'].left -= MOVESPEED + b['rect'].top += MOVESPEED + + if b['dir'] == DOWNRIGHT: + b['rect'].left += MOVESPEED + b['rect'].top += MOVESPEED + + if b['dir'] == UPLEFT: + b['rect'].left -= MOVESPEED + b['rect'].top -= MOVESPEED + + if b['dir'] == UPRIGHT: + b['rect'].left += MOVESPEED + b['rect'].top -= MOVESPEED + + # check if the block has moved out of the window + if b['rect'].top < 0: + # block has moved past the top + if b['dir'] == UPLEFT: + b['dir'] = DOWNLEFT + b['color'] = RED + if b['dir'] == UPRIGHT: + b['dir'] = DOWNRIGHT + b['color'] = RED + + if b['rect'].bottom > WINDOWHEIGHT: + # block has moved past the bottom + if b['dir'] == DOWNLEFT: + b['dir'] = UPLEFT + b['color'] = WHITE + if b['dir'] == DOWNRIGHT: + b['dir'] = UPRIGHT + b['color'] = WHITE + + if b['rect'].left < 0: + # block has moved past the left side + if b['dir'] == DOWNLEFT: + b['dir'] = DOWNRIGHT + b['color'] = GREEN + if b['dir'] == UPLEFT: + b['dir'] = UPRIGHT + b['color'] = GREEN + + if b['rect'].right > WINDOWWIDTH: + # block has moved past the right side + if b['dir'] == DOWNRIGHT: + b['dir'] = DOWNLEFT + b['color'] = BLUE + if b['dir'] == UPRIGHT: + b['dir'] = UPLEFT + b['color'] = BLUE + + # draw the block onto the surface + pygame.draw.rect(windowSurface, b['color'],b['rect']) + + # draw the window onto the screen + pygame.display.update() + + + timer.set_interval(draw,50) + + +.. code-block:: python + + import pygame, sys , time + from pygame.locals import * + + # set up pygame + pygame.init() + + # set up the window + WINDOWWIDTH = 400 + WINDOWHEIGHT = 400 + windowSurface = pygame.display.set_mode((WINDOWWIDNTH,WINDOWHEIGHT),0,32) + pygame.display.set_caption('Animation') + + # set up the direction variables + DOWNLEFT = 1 + DOWNRIGHT = 3 + UPLEFT = 7 + UPRIGHT = 9 + + MOVESPEED = 4 + + +.. code-block:: python + + # set up the block data structure + b1 = {'rect':pygame.Rect(300,80,50,100),'color':RED,'dir':UPRIGHT} + b2 = {'rect':pygame.Rect(200,200,20,20),'color':BLUE,'dir':UPLEFT} + b3 = {'rect':pygame.Rect(100,150,60,60),'color':GREEN,'dir':DOWNLEFT} + blocks = [b1,b2,b3] + + ++ Tenga en cuenta que en los diccionarios b1, b2 y b3 tengo objetos y direcciones + incrustado ++ Crea una lista de bloques con los tres diccionarios + + +.. code-block:: python + + while True: + # check for the QUIT event + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + + # draw the black background onto the surface + windowSurface.fill(BLACK) + + for b in blocks: + # move the block data structure + if b['dir'] == DOWNLEFT: + b['rect'].left -= MOVESPEED + b['rect'].top += MOVESPEED + + if b['dir'] == DOWNRIGHT: + b['rect'].left += MOVESPEED + b['rect'].top += MOVESPEED + + # check if the block has moved out of the window + if b['rect'].top < 0: + # block has moved past the top + if b['dir'] == UPLEFT: + b['dir'] = DOWNLEFT + if b['dir'] == UPRIGHT: + b['dir'] = DOWNRIGHT + + if b['rect'].bottom > WINDOWHEIGHT: + # block has moved past the bottom + if b['dir'] == DOWNLEFT: + b['dir'] = UPLEFT + if b['dir'] == DOWNRIGHT: + b['dir'] = UPRIGHT + + if b['rect'].left < 0: + # block has moved past the left side + if b['dir'] == DOWNLEFT: + b['dir'] = DOWNRIGHT + if b['dir'] == UPLEFT: + b['dir'] = UPRIGHT + + if b['rect'].right > WINDOWWIDTH: + # block has moved past the right side + if b['dir'] == DOWNRIGHT: + b['dir'] = DOWNLEFT + if b['dir'] == UPRIGHT: + b['dir'] = UPLEFT + + # draw the block onto the surface + pygame.draw.rect(windowSurface, b['color'],b['rect']) + + # draw the window onto the screen + pygame.display.update() + time.sleep(0.02) diff --git a/293/_sources/lectures/TWP60/TWP60_2_en.rst.txt b/293/_sources/lectures/TWP60/TWP60_2_en.rst.txt new file mode 100644 index 0000000000..402d44fa8d --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_2_en.rst.txt @@ -0,0 +1,217 @@ +Pygame Animation +================ + +.. image:: ../img/TWP60_007.png + :height: 11.826cm + :width: 11.217cm + :align: center + :alt: + +.. image:: ../img/TWP60_008.png + :height: 11.747cm + :width: 10.503cm + :align: center + :alt: + +.. activecode:: ac_l60_2_en + :language: python3 + :python3_interpreter: brython + + from browser import load, document,timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + import pygame, sys, time + from pygame.locals import * + from pygame.color import * + + # set up the colors + BLACK = Color(0,0,0) + WHITE = Color(255,255,255) + RED = Color(255,0,0) + GREEN = Color(0,255,0) + BLUE = Color(0,0,255) + + # set up pygame + pygame.init() + + # set up the window + WINDOWWIDTH = 500 + WINDOWHEIGHT = 300 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + + # set up the direction variables + DOWNLEFT = 1 + DOWNRIGHT = 3 + UPLEFT = 7 + UPRIGHT = 9 + + MOVESPEED = 4 + + # set up the block data structure + b1 = {'rect':pygame.Rect(300,80,50,100),'color':RED,'dir':UPRIGHT} + b2 = {'rect':pygame.Rect(200,200,20,20),'color':BLUE,'dir':UPLEFT} + b3 = {'rect':pygame.Rect(100,150,60,60),'color':GREEN,'dir':DOWNLEFT} + blocks = [b1,b2,b3] + + def draw(): + # draw the black background onto the surface + windowSurface.fill(BLACK) + + for b in blocks: + # move the block data structure + if b['dir'] == DOWNLEFT: + b['rect'].left -= MOVESPEED + b['rect'].top += MOVESPEED + + if b['dir'] == DOWNRIGHT: + b['rect'].left += MOVESPEED + b['rect'].top += MOVESPEED + + if b['dir'] == UPLEFT: + b['rect'].left -= MOVESPEED + b['rect'].top -= MOVESPEED + + if b['dir'] == UPRIGHT: + b['rect'].left += MOVESPEED + b['rect'].top -= MOVESPEED + + # check if the block has moved out of the window + if b['rect'].top < 0: + # block has moved past the top + if b['dir'] == UPLEFT: + b['dir'] = DOWNLEFT + b['color'] = RED + if b['dir'] == UPRIGHT: + b['dir'] = DOWNRIGHT + b['color'] = RED + + if b['rect'].bottom > WINDOWHEIGHT: + # block has moved past the bottom + if b['dir'] == DOWNLEFT: + b['dir'] = UPLEFT + b['color'] = WHITE + if b['dir'] == DOWNRIGHT: + b['dir'] = UPRIGHT + b['color'] = WHITE + + if b['rect'].left < 0: + # block has moved past the left side + if b['dir'] == DOWNLEFT: + b['dir'] = DOWNRIGHT + b['color'] = GREEN + if b['dir'] == UPLEFT: + b['dir'] = UPRIGHT + b['color'] = GREEN + + if b['rect'].right > WINDOWWIDTH: + # block has moved past the right side + if b['dir'] == DOWNRIGHT: + b['dir'] = DOWNLEFT + b['color'] = BLUE + if b['dir'] == UPRIGHT: + b['dir'] = UPLEFT + b['color'] = BLUE + + # draw the block onto the surface + pygame.draw.rect(windowSurface, b['color'],b['rect']) + + # draw the window onto the screen + pygame.display.update() + + timer.set_interval(draw,50) + + +.. code-block:: python + + import pygame, sys , time + from pygame.locals import * + + # set up pygame + pygame.init() + + # set up the window + WINDOWWIDTH = 400 + WINDOWHEIGHT = 400 + windowSurface = pygame.display.set_mode((WINDOWWIDNTH,WINDOWHEIGHT),0,32) + pygame.display.set_caption('Animation') + + # set up the direction variables + DOWNLEFT = 1 + DOWNRIGHT = 3 + UPLEFT = 7 + UPRIGHT = 9 + + MOVESPEED = 4 + + +.. code-block:: python + + # set up the block data structure + b1 = {'rect':pygame.Rect(300,80,50,100),'color':RED,'dir':UPRIGHT} + b2 = {'rect':pygame.Rect(200,200,20,20),'color':BLUE,'dir':UPLEFT} + b3 = {'rect':pygame.Rect(100,150,60,60),'color':GREEN,'dir':DOWNLEFT} + blocks = [b1,b2,b3] + ++ Note that in the b1, b2, and b3 dictionaries I have embedded objects and directions ++ Create a list of blocks with the three dictionaries + +.. code-block:: python + + while True: + # check for the QUIT event + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + + # draw the black background onto the surface + windowSurface.fill(BLACK) + + for b in blocks: + # move the block data structure + if b['dir'] == DOWNLEFT: + b['rect'].left -= MOVESPEED + b['rect'].top += MOVESPEED + + if b['dir'] == DOWNRIGHT: + b['rect'].left += MOVESPEED + b['rect'].top += MOVESPEED + + # check if the block has moved out of the window + if b['rect'].top < 0: + # block has moved past the top + if b['dir'] == UPLEFT: + b['dir'] = DOWNLEFT + if b['dir'] == UPRIGHT: + b['dir'] = DOWNRIGHT + + if b['rect'].bottom > WINDOWHEIGHT: + # block has moved past the bottom + if b['dir'] == DOWNLEFT: + b['dir'] = UPLEFT + if b['dir'] == DOWNRIGHT: + b['dir'] = UPRIGHT + + if b['rect'].left < 0: + # block has moved past the left side + if b['dir'] == DOWNLEFT: + b['dir'] = DOWNRIGHT + if b['dir'] == UPLEFT: + b['dir'] = UPRIGHT + + if b['rect'].right > WINDOWWIDTH: + # block has moved past the right side + if b['dir'] == DOWNRIGHT: + b['dir'] = DOWNLEFT + if b['dir'] == UPRIGHT: + b['dir'] = UPLEFT + + # draw the block onto the surface + pygame.draw.rect(windowSurface, b['color'],b['rect']) + + # draw the window onto the screen + pygame.display.update() + time.sleep(0.02) \ No newline at end of file diff --git a/293/_sources/lectures/TWP60/TWP60_3.rst.txt b/293/_sources/lectures/TWP60/TWP60_3.rst.txt new file mode 100644 index 0000000000..16a5eafec4 --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_3.rst.txt @@ -0,0 +1,126 @@ +Pygame Collision Detection +========================== + +.. image:: ../img/TWP60_014.png + :height: 8.492cm + :width: 12.117cm + :align: center + :alt: + +.. image:: ../img/TWP60_015.png + :height: 7.381cm + :width: 11.244cm + :align: center + :alt: + +.. code-block:: python + + def doRectsOverlap(rect1,rect2): + for a,b in [(rect1,rect2),(rect2,rect1)]: + # Check if a's corners are inside b + if ((isPointInsideRect(a.left,a.top,b)) or (isPointInsideRect(a.left,a.bottom,b)) or (isPointInsideRect(a.right,a.top,b)) or (isPointInsideRect(a.right,a.bottom,b))): + return True + + return False + + def isPointInsideRect(x,y,rect): + if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom): + return True + else: + return False + + +.. activecode:: ac_l60_3 + :language: python3 + :python3_interpreter: brython + + from browser import load, document,timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + import pygame, sys , time + from pygame.locals import * + from pygame.color import * + import random + + #set up the colors + BLACK = Color(0,0,0) + WHITE = Color(255,255,255) + RED = Color(255,0,0) + GREEN = Color(0,255,0) + BLUE = Color(0,0,255) + LIGHT_BLUE= Color(153,255,255) + # set up pygame + pygame.init() + + #set up fonts + rectFont = pygame.font.SysFont('timesnewroman',10) + pointFont = pygame.font.SysFont('timesnewroman',10) + + # set up the window + WINDOWWIDTH = 560 + WINDOWHEIGHT = 350 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + + def doRectsOverlap(rect1,rect2): + for a,b in [(rect1,rect2),(rect2,rect1)]: + # Check if a's corners are inside b + if ((isPointInsideRect(a.left,a.top,b)) or (isPointInsideRect(a.left,a.bottom,b)) or (isPointInsideRect(a.right,a.top,b)) or (isPointInsideRect(a.right,a.bottom,b))): + return True + + return False + + def isPointInsideRect(x,y,rect): + if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom): + return True + else: + return False + + + #define 4 rectangles + r1 = {'rect':pygame.Rect(300,80,50,50),'name':"Rect1",'color':RED} + r2 = {'rect':pygame.Rect(250,200,60,60),'name':"Rect2",'color':GREEN} + r3 = {'rect':pygame.Rect(100,150,80,40),'name':"Rect3",'color':BLUE} + r4 = {'rect':pygame.Rect(200,150,60,70),'name':"Rect4",'color':LIGHT_BLUE} + rects = [r1,r2,r3,r4] + + windowSurface.fill(BLACK) + #draw rectangles + for r in rects: + pygame.draw.rect(windowSurface, r['color'],r['rect']) + text = rectFont.render(r['name'],False,BLACK,r['color']) + textRect = text.get_rect() + textRect.centerx = r['rect'].left + (r['rect'].width)//2 + textRect.centery = r['rect'].top + (r['rect'].height)//2 + windowSurface.blit(text, textRect) + + #draw random points + point_size = 5 + num_points = 10 + points = [] + for i in range(num_points): + points.append({'pos':(random.randint(0,WINDOWWIDTH - point_size*10),random.randint(0,WINDOWHEIGHT - point_size*10)),'name':("P"+str(i))}) + + for p in points: + pygame.draw.circle(windowSurface,WHITE,p['pos'],point_size,0) + text = pointFont.render(p['name'],False,WHITE,BLACK) + textRect = text.get_rect() + textRect.centerx = p['pos'][0] + textRect.centery = p['pos'][1] - (point_size +5) + windowSurface.blit(text, textRect) + + #check overlap between rectangles + rects_copy = rects.copy() + for rect1 in rects: + for rect2 in rects_copy: + if(rect1['name']!=rect2['name']): + if(doRectsOverlap(rect1['rect'],rect2['rect'])): + print("{} and {} are overlapping.\n".format(rect1['name'],rect2['name'])) + rects_copy.remove(rect1) + + # check if any point is inside a rectangles + for p in points: + for rect in rects: + if(isPointInsideRect(p['pos'][0], p['pos'][1], rect['rect'])): + print("Point {} is inside rectangle {}".format(p['name'], rect['name'])) \ No newline at end of file diff --git a/293/_sources/lectures/TWP60/TWP60_3_en.rst.txt b/293/_sources/lectures/TWP60/TWP60_3_en.rst.txt new file mode 100644 index 0000000000..b70de9d3af --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_3_en.rst.txt @@ -0,0 +1,126 @@ +Pygame Collision Detection +========================== + +.. image:: ../img/TWP60_014.png + :height: 3.327in + :width: 4.772in + :align: center + :alt: + +.. image:: ../img/TWP60_015.png + :height: 2.904in + :width: 4.427in + :align: center + :alt: + +.. code-block:: python + + def doRectsOverlap(rect1,rect2): + for a,b in [(rect1,rect2),(rect2,rect1)]: + # Check if a's corners are inside b + if ((isPointInsideRect(a.left,a.top,b)) or (isPointInsideRect(a.left,a.bottom,b)) or (isPointInsideRect(a.right,a.top,b)) or (isPointInsideRect(a.right,a.bottom,b))): + return True + + return False + + def isPointInsideRect(x,y,rect): + if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom): + return True + else: + return False + + +.. activecode:: ac_l60_3_en + :language: python3 + :python3_interpreter: brython + + from browser import load, document,timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + import pygame, sys , time + from pygame.locals import * + from pygame.color import * + import random + + #set up the colors + BLACK = Color(0,0,0) + WHITE = Color(255,255,255) + RED = Color(255,0,0) + GREEN = Color(0,255,0) + BLUE = Color(0,0,255) + LIGHT_BLUE= Color(153,255,255) + # set up pygame + pygame.init() + + #set up fonts + rectFont = pygame.font.SysFont('timesnewroman',10) + pointFont = pygame.font.SysFont('timesnewroman',10) + + # set up the window + WINDOWWIDTH = 560 + WINDOWHEIGHT = 350 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + + def doRectsOverlap(rect1,rect2): + for a,b in [(rect1,rect2),(rect2,rect1)]: + # Check if a's corners are inside b + if ((isPointInsideRect(a.left,a.top,b)) or (isPointInsideRect(a.left,a.bottom,b)) or (isPointInsideRect(a.right,a.top,b)) or (isPointInsideRect(a.right,a.bottom,b))): + return True + + return False + + def isPointInsideRect(x,y,rect): + if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom): + return True + else: + return False + + + #define 4 rectangles + r1 = {'rect':pygame.Rect(300,80,50,50),'name':"Rect1",'color':RED} + r2 = {'rect':pygame.Rect(250,200,60,60),'name':"Rect2",'color':GREEN} + r3 = {'rect':pygame.Rect(100,150,80,40),'name':"Rect3",'color':BLUE} + r4 = {'rect':pygame.Rect(200,150,60,70),'name':"Rect4",'color':LIGHT_BLUE} + rects = [r1,r2,r3,r4] + + windowSurface.fill(BLACK) + #draw rectangles + for r in rects: + pygame.draw.rect(windowSurface, r['color'], r['rect']) + text = rectFont.render(r['name'], False, BLACK, r['color']) + textRect = text.get_rect() + textRect.centerx = r['rect'].left + (r['rect'].width)//2 + textRect.centery = r['rect'].top + (r['rect'].height)//2 + windowSurface.blit(text, textRect) + + #draw random points + point_size = 5 + num_points = 10 + points = [] + for i in range(num_points): + points.append({'pos':(random.randint(0,WINDOWWIDTH - point_size*10),random.randint(0,WINDOWHEIGHT - point_size*10)),'name':("P"+str(i))}) + + for p in points: + pygame.draw.circle(windowSurface, WHITE, p['pos'], point_size, 0) + text = pointFont.render(p['name'], False, WHITE, BLACK) + textRect = text.get_rect() + textRect.centerx = p['pos'][0] + textRect.centery = p['pos'][1] - (point_size +5) + windowSurface.blit(text, textRect) + + #check overlap between rectangles + rects_copy = rects.copy() + for rect1 in rects: + for rect2 in rects_copy: + if(rect1['name']!=rect2['name']): + if(doRectsOverlap(rect1['rect'],rect2['rect'])): + print("{} and {} are overlapping.\n".format(rect1['name'],rect2['name'])) + rects_copy.remove(rect1) + + # check if any point is inside a rectangles + for p in points: + for rect in rects: + if(isPointInsideRect(p['pos'][0], p['pos'][1], rect['rect'])): + print("Point {} is inside rectangle {}".format(p['name'], rect['name'])) \ No newline at end of file diff --git a/293/_sources/lectures/TWP60/TWP60_4.rst.txt b/293/_sources/lectures/TWP60/TWP60_4.rst.txt new file mode 100644 index 0000000000..f321dddcb2 --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_4.rst.txt @@ -0,0 +1,174 @@ +Pygame Input +============ + +.. image:: ../img/TWP60_017.png + :height: 11.614cm + :width: 11.085cm + :align: center + :alt: + +.. activecode:: ac_l60_4 + :language: python3 + :python3_interpreter: brython + + from browser import load, document,timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + import pygame, sys, random + from pygame.locals import * + + # set up pygame + pygame.init() + gamejs = window.gamejs + gamejs.ready() + + # set up the window + WINDOWWIDTH = 500 + WINDOWHEIGHT = 300 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + #pygame.display.set_caption('Input') + + # set up the colors + BLACK = pygame.color.Color(0,0,0) + GREEN = pygame.color.Color(0,255,0) + WHITE = pygame.color.Color(255,255,255) + + # set up the player and food data structure + foodCounter = 0 + NEWFOOD = 40 + FOODSIZE = 20 + player = pygame.Rect(300,100,50,50) + + foods = [] + for i in range(20): + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH - FOODSIZE),random.randint(0,WINDOWHEIGHT - FOODSIZE),FOODSIZE,FOODSIZE)) + + # set up the movement variables + + moveLeft = False + moveRight = False + moveUp = False + moveDown = False + + MOVESPEED = 6 + + def func(): + windowSurface.fill(BLACK) + # check for events + global moveLeft, moveRight, moveUp, moveDown + for event in pygame.event.get(): + if event.type == KEYDOWN: + # change the keyboard variables + if event.key == K_LEFT or event.key == ord('a'): + moveRight = False + moveLeft = True + if event.key == K_RIGHT or event.key == ord('d'): + moveLeft = False + moveRight = True + if event.key == K_UP or event.key == ord('w'): + moveDown = False + moveUp = True + if event.key == K_DOWN or event.key == ord('s'): + moveDown = True + moveUp = False + if moveRight: + player.left += MOVESPEED + if moveLeft: + player.left -= MOVESPEED + if moveUp: + player.top -= MOVESPEED + if moveDown: + player.top += MOVESPEED + + pygame.draw.rect(windowSurface,WHITE,player) + + # check if the player has intersected with any food squares. + for food in foods[:]: + if player.colliderect(food): + foods.remove(food) + + # draw the food + for i in range(len(foods)): + pygame.draw.rect(windowSurface,GREEN,foods[i]) + + # draw the window onto the screen + pygame.display.update() + + + timer.set_interval(func,30) + + +.. code-block:: python + + import pygame, sys, random + from pygame.locals import * + + # set up pygame + pygame.init() + mainClock = pygame.time.Clock() + + # set up the window + WINDOWWIDTH = 400 + WINDOWHEIGHT = 400 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + pygame.display.set_caption('Input') + + # set up the colors + BLACK = (0,0,0) + GREEN = (0,255,0) + WHITE = (255,255,255) + + # set up the player and food data structure + foodCounter = 0 + NEWFOOD = 40 + FOODSIZE = 20 + player = pygame.Rect(300,100,50,50) + + foods = [] + for i in range(20): + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH - FOODSIZE),random.randint(0,WINDOWHEIGHT - FOODSIZE),FOODSIZE,FOODSIZE)) + + # set up the movement variables + + moveLeft = False + moveRight = False + moveUp = False + moveDown = False + + MOVESPEED = 6 + + while True: + # check for events + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + if event.type == KEYDOWN: + # change the keyboard variables + if event.key == K_LEFT or event.key == ord('a'): + moveRight = False + moveLeft = True + if event.key == K_RIGHT or event.key == ord('d'): + moveLeft = False + moveRight = True + if event.key == K_UP or event.key == ord('w'): + moveDown = False + moveUp = True + + # draw the player onto the surface + pygame.draw.rect(windowSurface,WHITE,player) + + # check if the player has intersected with any food squares. + for food in foods[:]: + if player.colliderect(food): + foods.remove(food) + + # draw the food + for i in range(len(foods)): + pygame.draw.rect(windowSurface,GREEN,foods[i]) + + # draw the window onto the screen + pygame.display.update() + mainClock.tick(40) diff --git a/293/_sources/lectures/TWP60/TWP60_4_en.rst.txt b/293/_sources/lectures/TWP60/TWP60_4_en.rst.txt new file mode 100644 index 0000000000..b1ce53a3ed --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_4_en.rst.txt @@ -0,0 +1,177 @@ +Pygame Input +============ + +.. image:: ../img/TWP60_017.png + :height: 11.614cm + :width: 11.085cm + :align: center + :alt: + +.. activecode:: ac_l60_4_en + :language: python3 + :python3_interpreter: brython + + from browser import load, document,timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + import pygame, sys, random + from pygame.locals import * + + # set up pygame + pygame.init() + gamejs = window.gamejs + gamejs.ready() + + # set up the window + WINDOWWIDTH = 500 + WINDOWHEIGHT = 300 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + #pygame.display.set_caption('Input') + + # set up the colors + BLACK = pygame.color.Color(0,0,0) + GREEN = pygame.color.Color(0,255,0) + WHITE = pygame.color.Color(255,255,255) + + # set up the player and food data structure + foodCounter = 0 + NEWFOOD = 40 + FOODSIZE = 20 + player = pygame.Rect(300,100,50,50) + + foods = [] + for i in range(20): + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH - FOODSIZE),random.randint(0,WINDOWHEIGHT - FOODSIZE),FOODSIZE,FOODSIZE)) + + # set up the movement variables + + moveLeft = False + moveRight = False + moveUp = False + moveDown = False + + MOVESPEED = 6 + + def func(): + windowSurface.fill(BLACK) + # check for events + global moveLeft, moveRight, moveUp, moveDown + for event in pygame.event.get(): + if event.type == KEYDOWN: + # change the keyboard variables + if event.key == K_LEFT or event.key == ord('a'): + moveRight = False + moveLeft = True + if event.key == K_RIGHT or event.key == ord('d'): + moveLeft = False + moveRight = True + if event.key == K_UP or event.key == ord('w'): + moveDown = False + moveUp = True + if event.key == K_DOWN or event.key == ord('s'): + moveDown = True + moveUp = False + if moveRight: + player.left += MOVESPEED + if moveLeft: + player.left -= MOVESPEED + if moveUp: + player.top -= MOVESPEED + if moveDown: + player.top += MOVESPEED + + pygame.draw.rect(windowSurface,WHITE,player) + + # check if the player has intersected with any food squares. + for food in foods[:]: + if player.colliderect(food): + foods.remove(food) + + # draw the food + for i in range(len(foods)): + pygame.draw.rect(windowSurface,GREEN,foods[i]) + + # draw the window onto the screen + pygame.display.update() + + + timer.set_interval(func,30) + + +.. code-block:: python + + import pygame, sys, random + from pygame.locals import * + + # set up pygame + pygame.init() + mainClock = pygame.time.Clock() + + # set up the window + WINDOWWIDTH = 400 + WINDOWHEIGHT = 400 + windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),0,32) + pygame.display.set_caption('Input') + + # set up the colors + BLACK = (0,0,0) + GREEN = (0,255,0) + WHITE = (255,255,255) + + # set up the player and food data structure + foodCounter = 0 + NEWFOOD = 40 + FOODSIZE = 20 + player = pygame.Rect(300,100,50,50) + + foods = [] + for i in range(20): + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH - FOODSIZE),random.randint(0,WINDOWHEIGHT - FOODSIZE),FOODSIZE,FOODSIZE)) + + # set up the movement variables + + moveLeft = False + moveRight = False + moveUp = False + moveDown = False + + MOVESPEED = 6 + + while True: + # check for events + for event in pygame.event.get(): + if event.type == QUIT: + pygame.quit() + sys.exit() + if event.type == KEYDOWN: + # change the keyboard variables + if event.key == K_LEFT or event.key == ord('a'): + moveRight = False + moveLeft = True + if event.key == K_RIGHT or event.key == ord('d'): + moveLeft = False + moveRight = True + if event.key == K_UP or event.key == ord('w'): + moveDown = False + moveUp = True + if event.key == K_DOWN or event.key == ord('s'): + moveDown = True + moveUp = False + + # draw the player onto the surface + pygame.draw.rect(windowSurface,WHITE,player) + + # check if the player has intersected with any food squares. + for food in foods[:]: + if player.colliderect(food): + foods.remove(food) + + # draw the food + for i in range(len(foods)): + pygame.draw.rect(windowSurface,GREEN,foods[i]) + + # draw the window onto the screen + pygame.display.update() + mainClock.tick(40) \ No newline at end of file diff --git a/293/_sources/lectures/TWP60/TWP60_5.rst.txt b/293/_sources/lectures/TWP60/TWP60_5.rst.txt new file mode 100644 index 0000000000..b6ce162a7f --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_5.rst.txt @@ -0,0 +1,202 @@ +Sounds and Sprites +================== + + +.. image:: ../img/TWP60_022.png + :height: 6.164cm + :width: 13.202cm + :align: center + :alt: + + +.. image:: ../img/TWP60_023.png + :height: 11.561cm + :width: 13.546cm + :align: center + :alt: + + +.. activecode:: ac_l60_5 + :language: python3 + :python3_interpreter: brython + + from browser import load, timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + # Sprites + + import pygame + import random + + # GLOBAL VARIABLES + COLOR = pygame.color.Color(255, 100, 98) + SURFACE_COLOR = pygame.color.Color(167, 255, 100) + WIDTH = 500 + HEIGHT = 300 + + # Object class + class Sprite(pygame.sprite.Sprite): + def __init__(self, color, height, width): + super().__init__() + + self.image = pygame.Surface([width, height]) + self.image.fill(SURFACE_COLOR) + self.image.set_colorkey(COLOR) + + pygame.draw.rect(self.image,color,pygame.Rect(0, 0, width, height)) + + self.rect = self.image.get_rect() + + + pygame.init() + + RED = pygame.color.Color(255, 0, 0) + + size = (WIDTH, HEIGHT) + screen = pygame.display.set_mode(size) + all_sprites_list = pygame.sprite.Group() + + object_ = Sprite(RED, 50, 30) + object_.rect.x = 50 + object_.rect.y = 50 + + all_sprites_list.add(object_) + + + + def func(): + all_sprites_list.update() + screen.fill(SURFACE_COLOR) + all_sprites_list.draw(screen) + pygame.display.flip() + + + timer.set_interval(func,60) + + + +.. activecode:: ac_l60_51 + :language: python3 + :python3_interpreter: brython + + from browser import load, timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + # Sounds + from pygame import mixer + + # Starting the mixer + mixer.init() + + # Loading the song + mixer.music.load("../../audio/Example04_Tour01_Line01.wav") + + # Setting the volume + mixer.music.set_volume(0.7) + + # Start playing the song + mixer.music.play() + + + + +.. code-block:: python + + + # set up the block data structure + player = pygame.Rect(300,100,40,40) + playerImage = pygame.image.load('player.png') + plyaerStretchedImage = pygame.transform.scale(playerImage(40,40)) + foodImage = pygame.image.load('cherry.png') + foods = [] + for i in range(20): + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH - 20),random.randint(0,WINDOWHEIGHT - 20),20,20)) + + ++ Player.png aparece en la escala deseada ++ Genero aleatoriamente 20 cerezas iniciales + + +.. code-block:: python + + # set up music + + pickUpSound = pygame.mixer.Sound('pickup.wav') + pygame.mixer.music.load('background.mid') + pygame.mixer.music.play(-1,0.0) + musicPlaying = True + + ++ Uso dos canales, uno para música de fondo y uno para cada + cereza escogida + + +.. code-block:: python + + if event.key == ord('m'): + if musicPlaying: + pygame.mixer.music.stop() + else: + pygame.mixer.music.play(-1,0,0) + musicPlaying = not musicPlaying + + if event.type == MOUSEBUTTONUP: + foods.append(pygame.Rect(event.pos[0]-10,event.pos[1] - 10,20,20)) + + + ++ Tecla ‘m’ pausa o fundo musical e o click do mouse planta uma + cerejinha na posição clicada + + +.. code-block:: python + + foodCounter += 1 + if foodCounter >= NEWFOOD: + #add new food + foodCounter = 0 + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH-20),random.randint(0,WINDOWHEIGHT - 20),20,20)) + + ++ Las cerezas se generan aleatoriamente con cada pasada en el bucle. + principal + + +.. code-block:: python + + # check if the block has intersected with any food squares. + for food in foods[:]: + if player.colliderect(food): + foods.remove(food) + player = pygame.Rect(player.left,player.top,player.right,player.down) + playerStretchedImage = pygame.transform.scale(player.left,player.top,player.right,player.down) + if musicPlaying: + pickUpSound.play() + + # draw the food + for food in foods: + windowSurface.blit(foodImage,food) + + + ++ Removo cerejas “comidas”, claro engordando! ++ Todas as “blitadas” aparecem no update ++ FPS == Frames Per Second ++ Variável que controla o mainClock.tick() ++ Os monstrinhos possuem um tamanho mínimo e máximo e sua velocidade é + controlada + +.. code-block:: python + + if baddieAddCounter == ADDNEWBADDIERATE: + baddieAddCounter = 0 + baddieSize = random.randint(BADDIEMINSIZE,BADDIEMAXSIZE) + newBaddie = {'rect':pygame.Rect(random.randint(0,WINDOWWIDTH-baddieSize),0-baddieSize,baddieSize,baddieSize),'speed':random.randint(BADDIEMINSPEED,BADDIEMAXSPEED),'surface':pygame.transform.scale(baddieImage,(baddieSize,baddieSize))} + + baddies.append(newBaddie) diff --git a/293/_sources/lectures/TWP60/TWP60_5_en.rst.txt b/293/_sources/lectures/TWP60/TWP60_5_en.rst.txt new file mode 100644 index 0000000000..47a6fbce0f --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_5_en.rst.txt @@ -0,0 +1,202 @@ +Sounds and Sprites +================== + + +.. image:: ../img/TWP60_022.png + :height: 6.164cm + :width: 13.202cm + :align: center + :alt: + + +.. image:: ../img/TWP60_023.png + :height: 11.561cm + :width: 13.546cm + :align: center + :alt: + + +.. activecode:: ac_l60_5_en + :language: python3 + :python3_interpreter: brython + + from browser import load, timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + # Sprites + + import pygame + import random + + # GLOBAL VARIABLES + COLOR = pygame.color.Color(255, 100, 98) + SURFACE_COLOR = pygame.color.Color(167, 255, 100) + WIDTH = 500 + HEIGHT = 300 + + # Object class + class Sprite(pygame.sprite.Sprite): + def __init__(self, color, height, width): + super().__init__() + + self.image = pygame.Surface([width, height]) + self.image.fill(SURFACE_COLOR) + self.image.set_colorkey(COLOR) + + pygame.draw.rect(self.image,color,pygame.Rect(0, 0, width, height)) + + self.rect = self.image.get_rect() + + + pygame.init() + + RED = pygame.color.Color(255, 0, 0) + + size = (WIDTH, HEIGHT) + screen = pygame.display.set_mode(size) + all_sprites_list = pygame.sprite.Group() + + object_ = Sprite(RED, 50, 30) + object_.rect.x = 50 + object_.rect.y = 50 + + all_sprites_list.add(object_) + + + + def func(): + all_sprites_list.update() + screen.fill(SURFACE_COLOR) + all_sprites_list.draw(screen) + pygame.display.flip() + + + timer.set_interval(func,60) + + + +.. activecode:: ac_l60_5_en1_en + :language: python3 + :python3_interpreter: brython + + from browser import load, timer + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + + ^^^^ + + # Sounds + from pygame import mixer + + # Starting the mixer + mixer.init() + + # Loading the song + mixer.music.load("../../audio/Example04_Tour01_Line01.wav") + + # Setting the volume + mixer.music.set_volume(0.7) + + # Start playing the song + mixer.music.play() + + + + +.. code-block:: python + + + # set up the block data structure + player = pygame.Rect(300,100,40,40) + playerImage = pygame.image.load('player.png') + plyaerStretchedImage = pygame.transform.scale(playerImage(40,40)) + foodImage = pygame.image.load('cherry.png') + foods = [] + for i in range(20): + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH - 20),random.randint(0,WINDOWHEIGHT - 20),20,20)) + + ++ Player.png appears in the desired scale ++ Generate 20 initial cherries randomly + + +.. code-block:: python + + # set up music + + pickUpSound = pygame.mixer.Sound('pickup.wav') + pygame.mixer.music.load('background.mid') + pygame.mixer.music.play(-1,0.0) + musicPlaying = True + + ++ Use two channels, one for background music and one for each + picked cherry + + +.. code-block:: python + + if event.key == ord('m'): + if musicPlaying: + pygame.mixer.music.stop() + else: + pygame.mixer.music.play(-1,0,0) + musicPlaying = not musicPlaying + + if event.type == MOUSEBUTTONUP: + foods.append(pygame.Rect(event.pos[0]-10,event.pos[1] - 10,20,20)) + + + ++ Key 'm' pauses or resumes background music and mouse click plants a + cherry at clicked position + + +.. code-block:: python + + foodCounter += 1 + if foodCounter >= NEWFOOD: + #add new food + foodCounter = 0 + foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH-20),random.randint(0,WINDOWHEIGHT - 20),20,20)) + + ++ Cherries are randomly generated with each pass in the main loop. + principal + + +.. code-block:: python + + # check if the block has intersected with any food squares. + for food in foods[:]: + if player.colliderect(food): + foods.remove(food) + player = pygame.Rect(player.left,player.top,player.right,player.down) + playerStretchedImage = pygame.transform.scale(player.left,player.top,player.right,player.down) + if musicPlaying: + pickUpSound.play() + + # draw the food + for food in foods: + windowSurface.blit(foodImage,food) + + + ++ Remove "eaten" cherries, of course bulking up! ++ All blits appear in the update ++ FPS == Frames Per Second ++ Variable that controls the mainClock.tick() ++ The monsters have a minimum and maximum size and their speed is + controlled + +.. code-block:: python + + if baddieAddCounter == ADDNEWBADDIERATE: + baddieAddCounter = 0 + baddieSize = random.randint(BADDIEMINSIZE,BADDIEMAXSIZE) + newBaddie = {'rect':pygame.Rect(random.randint(0,WINDOWWIDTH-baddieSize),0-baddieSize,baddieSize,baddieSize),'speed':random.randint(BADDIEMINSPEED,BADDIEMAXSPEED),'surface':pygame.transform.scale(baddieImage,(baddieSize,baddieSize))} + + baddies.append(newBaddie) \ No newline at end of file diff --git a/293/_sources/lectures/TWP60/TWP60_6.rst.txt b/293/_sources/lectures/TWP60/TWP60_6.rst.txt new file mode 100644 index 0000000000..924c110361 --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_6.rst.txt @@ -0,0 +1,162 @@ +Eventos +======= + +.. raw:: html + + + + + +Los eventos en pygame se manejan a través del módulo pygame.event. +El método pygame.event.get() obtiene todos los eventos de la cola de eventos. +La cola de eventos es una lista de objetos de eventos enviados al programa por el administrador de ventanas. +o el propio programa pygame. +El método pygame.event.get() devuelve una lista de objetos pygame.event.Event. +Cada objeto de evento tiene un tipo de evento almacenado en el atributo de tipo. +El atributo de tipo se puede comparar con las constantes definidas en el módulo pygame.locals. +El módulo pygame.locals define constantes para los tipos de eventos. +Los tipos de eventos se utilizan para determinar qué tipo de evento ha ocurrido. +Los tipos de eventos se enumeran a continuación: + ++ KEYUP ++ KEYDOWN ++ MOUSEMOTION ++ MOUSEBUTTONUP ++ MOUSEBUTTONDOWN + +KEYDOWN es un tipo de evento que se dispara cuando se presiona una tecla. como cuando presionas una tecla en el teclado. + +KEYUP es un tipo de evento que se activa cuando se suelta una tecla. como cuando quitas el dedo de una tecla. + + +.. activecode:: ac_l60_6_en + :language: python3 + :python3_interpreter: brython + + from browser import load, timer, window + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + gjs = window.gamejs + gjs.ready() + + ^^^^ + import pygame + from pygame.locals import * + + # Pygame to show keyevents + # green box moves with arrow keys + + # set up the colors + BLACK = pygame.color.Color('black') + WHITE = pygame.color.Color('white') + GREEN = pygame.color.Color('green') + + screen = pygame.display.set_mode((400,300)) + screen.fill(WHITE) + pygame.draw.rect(screen, GREEN, pygame.Rect(100, 100, 50, 50)) + + blockX = 100 + blockY = 100 + + def main(): + + + # keyboard event loop + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + global blockX + global blockY + if event.key == pygame.K_LEFT: + blockX -= 10 + if event.key == pygame.K_RIGHT: + blockX += 10 + if event.key == pygame.K_UP: + blockY -= 10 + if event.key == pygame.K_DOWN: + blockY += 10 + + + screen.fill(WHITE) + pygame.draw.rect(screen, GREEN, pygame.Rect(blockX, blockY, 50, 50)) + + # draw the window onto the screen + pygame.display.update() + + + + + pygame.init() + + timer1 = timer.set_interval(main,80) + + +MOUSEMOTION es un tipo de evento que se dispara cuando se mueve el mouse. + +MOUSEBUTTONDOWN es un tipo de evento que se activa cuando se presiona un botón del mouse. + +MOUSEBUTTONUP es un tipo de evento que se activa cuando se suelta un botón del mouse. + + +.. activecode:: ac_l60_6_2 + :language: python3 + :python3_interpreter: brython + + from browser import load, timer, window + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + gjs = window.gamejs + gjs.ready() + + ^^^^ + import pygame + from pygame.locals import * + + # Pygame para mostrar eventos del mouse + # Si el mouse se está moviendo, mostraremos el texto "El mouse se está moviendo" + # Si se hace clic con el mouse, mostraremos el texto "Se hace clic con el mouse" + # Si se suelta el mouse, mostraremos el texto "Se suelta el mouse" + # También mostraremos la posición del mouse y en qué botón se hace clic + + BLACK = pygame.color.Color('black') + WHITE = pygame.color.Color('white') + GREEN = pygame.color.Color('green') + + screen = pygame.display.set_mode((800,800)) + screen.fill(GREEN) + + font=pygame.font.SysFont('timesnewroman',30) + left_key = font.render('se hace clic en el botón izquierdo del ratón',True,BLACK) + right_key = font.render('se hace clic en el botón derecho del ratón',True,BLACK) + mouse = font.render('El mouse se está moviendo',True,BLACK) + button_down = font.render('Se suelta el mouse',True,BLACK) + mouse_pos = font.render('Posición del mouse',True,BLACK) + + def main(): + + # mouse event loop + for event in pygame.event.get(): + screen.fill(GREEN) + if event.type == pygame.MOUSEMOTION: + screen.blit(mouse,(100,100)) + mouse_position = pygame.mouse.get_pos() + screen.blit(mouse_pos,(100,200)) + screen.blit(font.render(str(mouse_position),True,BLACK),(400,200)) + if event.type == pygame.MOUSEBUTTONUP: + mouse_keys = pygame.mouse.get_pressed() + if mouse_keys[0]: + screen.blit(left_key,(100,100)) + if mouse_keys[2]: + screen.blit(right_key,(100,100)) + else : + if event.type == pygame.MOUSEBUTTONDOWN: + screen.blit(button_down,(100,100)) + + pygame.display.update() + + pygame.init() + + timer1 = timer.set_interval(main,80) + + diff --git a/293/_sources/lectures/TWP60/TWP60_6_en.rst.txt b/293/_sources/lectures/TWP60/TWP60_6_en.rst.txt new file mode 100644 index 0000000000..50986cb19c --- /dev/null +++ b/293/_sources/lectures/TWP60/TWP60_6_en.rst.txt @@ -0,0 +1,159 @@ +Events +================ + +.. raw:: html + + + + + +Event in pygame are handled through the pygame.event module. +The pygame.event.get() method gets all the events from the event queue. +The event queue is a list of event objects that are sent to the program by the window manager +or by the pygame program itself. +The pygame.event.get() method returns a list of pygame.event.Event objects. +Each Event object has an event type stored in the type attribute. +The type attribute can be compared to the constants defined in the pygame.locals module. +The pygame.locals module defines constants for the event types. +The event types are used to determine what type of event has occurred. +The event types are listed below: + ++ KEYDOWN ++ KEYUP ++ MOUSEMOTION ++ MOUSEBUTTONDOWN ++ MOUSEBUTTONUP + +KEYDOWN is an event type that is fired when a key is pressed down. like when you press a key on the keyboard. + +KEYUP is an event type that is fired when a key is released. like when you lift your finger off a key. + +.. activecode:: ac_l60_6_1_en + :language: python3 + :python3_interpreter: brython + + from browser import load, timer, window + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + gjs = window.gamejs + gjs.ready() + + ^^^^ + import pygame + from pygame.locals import * + + # Pygame to show keyevents + # green box moves with arrow keys + + # set up the colors + BLACK = pygame.color.Color('black') + WHITE = pygame.color.Color('white') + GREEN = pygame.color.Color('green') + + screen = pygame.display.set_mode((400,300)) + screen.fill(WHITE) + pygame.draw.rect(screen, GREEN, pygame.Rect(100, 100, 50, 50)) + + blockX = 100 + blockY = 100 + + def main(): + + + # keyboard event loop + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + global blockX + global blockY + if event.key == pygame.K_LEFT: + blockX -= 10 + if event.key == pygame.K_RIGHT: + blockX += 10 + if event.key == pygame.K_UP: + blockY -= 10 + if event.key == pygame.K_DOWN: + blockY += 10 + + + screen.fill(WHITE) + pygame.draw.rect(screen, GREEN, pygame.Rect(blockX, blockY, 50, 50)) + + # draw the window onto the screen + pygame.display.update() + + + + + pygame.init() + + timer1 = timer.set_interval(main,80) + + +MOUSEMOTION is an event type that is fired when the mouse is moved. + +MOUSEBUTTONDOWN is an event type that is fired when a mouse button is pressed down. + +MOUSEBUTTONUP is an event type that is fired when a mouse button is released. + +.. activecode:: ac_l60_6_2_en + :language: python3 + :python3_interpreter: brython + + from browser import load, timer, window + load('../../_static/game.js') + load('../../_static/pygame.brython.js') + gjs = window.gamejs + gjs.ready() + + ^^^^ + import pygame + from pygame.locals import * + + # Pygame to show mouse events + # If mouse is moving, we will display the text "Mouse is moving" + # If mouse is clicked, we will display the text "Mouse is clicked" + # If mouse is released, we will display the text "Mouse is released" + # We will also display the mouse position and which button is clicked + + BLACK = pygame.color.Color('black') + WHITE = pygame.color.Color('white') + GREEN = pygame.color.Color('green') + + screen = pygame.display.set_mode((800,800)) + screen.fill(GREEN) + + font=pygame.font.SysFont('timesnewroman',30) + left_key = font.render('Left mouse button clicked',True,BLACK) + right_key = font.render('Right mouse button clicked',True,BLACK) + mouse = font.render('Mouse is moving',True,BLACK) + button_down = font.render('Mouse button is pressed down',True,BLACK) + mouse_pos = font.render('Mouse position is : ',True,BLACK) + + def main(): + + # mouse event loop + for event in pygame.event.get(): + screen.fill(GREEN) + if event.type == pygame.MOUSEMOTION: + screen.blit(mouse,(100,100)) + mouse_position = pygame.mouse.get_pos() + screen.blit(mouse_pos,(100,200)) + screen.blit(font.render(str(mouse_position),True,BLACK),(400,200)) + if event.type == pygame.MOUSEBUTTONUP: + mouse_keys = pygame.mouse.get_pressed() + if mouse_keys[0]: + screen.blit(left_key,(100,100)) + if mouse_keys[2]: + screen.blit(right_key,(100,100)) + else : + if event.type == pygame.MOUSEBUTTONDOWN: + screen.blit(button_down,(100,100)) + + pygame.display.update() + + pygame.init() + + timer1 = timer.set_interval(main,80) + diff --git a/293/_sources/lectures/TWP60/toctree.rst.txt b/293/_sources/lectures/TWP60/toctree.rst.txt new file mode 100644 index 0000000000..8c1511dbf8 --- /dev/null +++ b/293/_sources/lectures/TWP60/toctree.rst.txt @@ -0,0 +1,23 @@ +====== +Pygame +====== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP60_1.rst + TWP60_2.rst + TWP60_3.rst + TWP60_4.rst + TWP60_5.rst + TWP60_6.rst diff --git a/293/_sources/lectures/TWP60/toctree_en.rst.txt b/293/_sources/lectures/TWP60/toctree_en.rst.txt new file mode 100644 index 0000000000..e86da44d8b --- /dev/null +++ b/293/_sources/lectures/TWP60/toctree_en.rst.txt @@ -0,0 +1,23 @@ +====== +Pygame +====== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP60_1_en.rst + TWP60_2_en.rst + TWP60_3_en.rst + TWP60_4_en.rst + TWP60_5_en.rst + TWP60_6_en.rst diff --git a/293/_sources/lectures/TWP65/TWP65_1.rst.txt b/293/_sources/lectures/TWP65/TWP65_1.rst.txt new file mode 100644 index 0000000000..ba92045b0c --- /dev/null +++ b/293/_sources/lectures/TWP65/TWP65_1.rst.txt @@ -0,0 +1,51 @@ +Desarrollo web +============== + +Solicitudes y respuestas +------------------------ + + +.. image:: ../img/TWP65_001.jpg + :height: 15.139cm + :width: 16.053cm + :align: center + :alt: + + +.. image:: ../img/TWP65_002.jpg + :height: 16.017cm + :width: 15.601cm + :align: center + :alt: + + + ++ "Python: el único lenguaje con más marcos web que palabras clave" ++ Frameworks: Plone, Django, Web2py, Pyramid ++ Micro Frameworks: CherryPy, Botella, Frasco ++ WSGI (interfaz de puerta de enlace del servidor web) + + + Patrones de acceso y comunicación entre servidores web y aplicaciones Python + + No es J2EE ;-) + + +Web2py +------ + ++ InfoWorld: best full-stack Python framework ++ Bossie: Best Open Source Development Software ++ MVC: + + + Modelo: datos + + Controladores: reglas de negocio + + Vistas: presentación + ++ Autocontido == full-stack framework ++ Seguro ++ DAL (Data Access Layer) ++ Deploy rápido e distribuição fácil ++ Princípios Python + + + DRY – Don’t Repeat Yourself + + Debe haber solo una forma obvia de hacer algo + + Explícito es mejor que implícito (no sigue) diff --git a/293/_sources/lectures/TWP65/TWP65_1_en.rst.txt b/293/_sources/lectures/TWP65/TWP65_1_en.rst.txt new file mode 100644 index 0000000000..77f49fd2fb --- /dev/null +++ b/293/_sources/lectures/TWP65/TWP65_1_en.rst.txt @@ -0,0 +1,46 @@ +Web Development +=============== + +Requests and Responses +---------------------- + +.. image:: ../img/TWP65_001.jpg + :height: 15.139cm + :width: 16.053cm + :align: center + :alt: + +.. image:: ../img/TWP65_002.jpg + :height: 16.017cm + :width: 15.601cm + :align: center + :alt: + ++ "Python: the only language with more web frameworks than keywords" ++ Frameworks: Plone, Django, Web2py, Pyramid ++ Micro Frameworks: CherryPy, Bottle, Flask ++ WSGI (Web Server Gateway Interface) + + + Access patterns and communication between web servers and Python applications + + Not J2EE ;-) + +Web2py +------ + ++ InfoWorld: best full-stack Python framework ++ Bossie: Best Open Source Development Software ++ MVC: + + + Model: data + + Controllers: business rules + + Views: presentation + ++ Self-contained == full-stack framework ++ Secure ++ DAL (Data Access Layer) ++ Fast deployment and easy distribution ++ Python Principles + + + DRY – Don’t Repeat Yourself + + There should be one-- and preferably only one --obvious way to do it. + + Explicit is better than implicit (doesn't follow) \ No newline at end of file diff --git a/293/_sources/lectures/TWP65/TWP65_2.rst.txt b/293/_sources/lectures/TWP65/TWP65_2.rst.txt new file mode 100644 index 0000000000..5feb22daea --- /dev/null +++ b/293/_sources/lectures/TWP65/TWP65_2.rst.txt @@ -0,0 +1,56 @@ +Hello World +=========== + + ++ Habilite la opción "No usar servidor proxy para servidores locales" ++ web2py.exe en el directorio descomprimido ++ Establecer una contraseña de administrador ++ Haga clic en "Interfaz administrativa" ++ Ingrese la contraseña que configuró ++ Tres opciones: administrador, ejemplos y bienvenida ++ Luego aprenderemos a usar electrodomésticos ++ Nueva aplicación básica: "Hola Mundo" ++ Edite el controlador default.py + +.. code-block:: python + + + def index(): + return "Mi primer mensaje" + + ++ ctrl+S ++ Regrese y haga clic en Hello World + + ++ Edite el controlador nuevamente default.py + +.. code-block:: python + + def index(): + return dict(msg="FATEC SJC") + + ++ ctrl+S ++ Ahora editemos la vista default/index + + ++ Borra todo y cambia la vista default/index + +.. code-block:: html + + + + + + + + +

{{=msg}}

+ + + + + + ++ ctrl+S diff --git a/293/_sources/lectures/TWP65/TWP65_2_en.rst.txt b/293/_sources/lectures/TWP65/TWP65_2_en.rst.txt new file mode 100644 index 0000000000..8dfe643eab --- /dev/null +++ b/293/_sources/lectures/TWP65/TWP65_2_en.rst.txt @@ -0,0 +1,56 @@ +Hello World +=========== + + ++ Enable the "Do not use proxy server for local servers" option ++ web2py.exe in the extracted directory ++ Set an administrator password ++ Click on "Administrative Interface" ++ Enter the password you configured ++ Three options: administrator, examples and welcome ++ Then we will learn how to use appliances ++ New basic application: "Hello World" ++ Edit the default.py controller + +.. code-block:: python + + + def index(): + return "My first message" + + ++ ctrl+S ++ Go back and click on Hello World + + ++ Edit the default.py controller again + +.. code-block:: python + + def index(): + return dict(msg="FATEC SJC") + + ++ ctrl+S ++ Now let's edit the default/index view + + ++ Delete everything and change the default/index view + +.. code-block:: html + + + + + + + + +

{{=msg}}

+ + + + + + ++ ctrl+S \ No newline at end of file diff --git a/293/_sources/lectures/TWP65/TWP65_3.rst.txt b/293/_sources/lectures/TWP65/TWP65_3.rst.txt new file mode 100644 index 0000000000..acfdad6b23 --- /dev/null +++ b/293/_sources/lectures/TWP65/TWP65_3.rst.txt @@ -0,0 +1,100 @@ +Cuentas visitantes +================== + + ++ Editar controlador default.py + + +.. code-block:: python + + + def index(): + + if not session.counter: + + session.counter = 1 + + else: + + session.counter += 1 + + return dict(msg="Python Zumbi", cont=session.counter) + + ++ Vista default/index + +.. code-block:: html + + + + + + + + +

{{=msg}}

+ +

Visitantes: {{=cont}}

+ + + + + + ++ Diferentes visitantes tienen diferentes contadores + + +Dos paginas +----------- + ++ Crearemos dos páginas ++ El primero pide el nombre en un formulario ++ Luego seremos redirigidos a la segunda ++ El segundo dará un saludo con el nombre ++ Incluir en el controlador default.py + +.. code-block:: python + + + def primeira(): + + return dict() + + def segunda(): + + return dict() + + ++ Crea la visión default/primeira + + +{{extend 'layout.html'}} + +Qual é o seu nome? + +
+ + + + + +
+ + ++ Crea la visión default/segunda + + +{{extend 'layout.html'}} + +

Olá {{=request.vars.nome}}

+ + +Accesorios +---------- + ++ `Web2py Appliances `_ ++ Email Contact Form ++ Sudoku Solver ++ Train Counter Game ++ Quiz Builder ++ EcardsOnMap (es grande...) diff --git a/293/_sources/lectures/TWP65/TWP65_3_en.rst.txt b/293/_sources/lectures/TWP65/TWP65_3_en.rst.txt new file mode 100644 index 0000000000..1f361361e2 --- /dev/null +++ b/293/_sources/lectures/TWP65/TWP65_3_en.rst.txt @@ -0,0 +1,100 @@ +Visitor Accounts +================ + + ++ Edit default.py controller + + +.. code-block:: python + + + def index(): + + if not session.counter: + + session.counter = 1 + + else: + + session.counter += 1 + + return dict(msg="Python Zumbi", cont=session.counter) + + ++ default/index view + +.. code-block:: html + + + + + + + + +

{{=msg}}

+ +

Visitors: {{=cont}}

+ + + + + + ++ Different visitors have different counters + + +Two pages +--------- + ++ We will create two pages ++ The first asks for the name in a form ++ Then we will be redirected to the second ++ The second will give a greeting with the name ++ Include in the default.py controller + +.. code-block:: python + + + def first(): + + return dict() + + def second(): + + return dict() + + ++ Create the default/first view + + +{{extend 'layout.html'}} + +What is your name? + +
+ + + + + +
+ + ++ Create the default/second view + + +{{extend 'layout.html'}} + +

Hello {{=request.vars.name}}

+ + +Accessories +----------- + ++ `Web2py Appliances `_ ++ Email Contact Form ++ Sudoku Solver ++ Train Counter Game ++ Quiz Builder ++ EcardsOnMap (it's huge...) \ No newline at end of file diff --git a/293/_sources/lectures/TWP65/toctree.rst.txt b/293/_sources/lectures/TWP65/toctree.rst.txt new file mode 100644 index 0000000000..6dc32876d3 --- /dev/null +++ b/293/_sources/lectures/TWP65/toctree.rst.txt @@ -0,0 +1,20 @@ +============================== +Introducción al desarrollo web +============================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP65_1.rst + TWP65_2.rst + TWP65_3.rst diff --git a/293/_sources/lectures/TWP65/toctree_en.rst.txt b/293/_sources/lectures/TWP65/toctree_en.rst.txt new file mode 100644 index 0000000000..de99f27c82 --- /dev/null +++ b/293/_sources/lectures/TWP65/toctree_en.rst.txt @@ -0,0 +1,20 @@ +============================== +Introduction to Web Development +============================== + + +.. image:: ../img/TWP10_001.jpeg + :height: 14.925cm + :width: 9.258cm + :align: center + :alt: + + +.. toctree:: + :caption: Contenido + :maxdepth: 1 + :numbered: + + TWP65_1_en.rst + TWP65_2_en.rst + TWP65_3_en.rst diff --git a/293/_sources/lectures/_static/interpreter.html.txt b/293/_sources/lectures/_static/interpreter.html.txt new file mode 100644 index 0000000000..542d1598d5 --- /dev/null +++ b/293/_sources/lectures/_static/interpreter.html.txt @@ -0,0 +1,59 @@ + +
+ +
\ No newline at end of file diff --git a/293/_sources/quiz/Quiz1.rst.txt b/293/_sources/quiz/Quiz1.rst.txt new file mode 100644 index 0000000000..502f961e63 --- /dev/null +++ b/293/_sources/quiz/Quiz1.rst.txt @@ -0,0 +1,322 @@ +======== +Quiz - 1 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz1 + + .. tab:: Ejercicio 1 + + .. activecode:: q1_1 + :nocodelens: + + Haga un programa que pida dos números enteros e imprima la suma de esos dos números. |br| + + ~~~~ + def suma(n, m): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(suma(24, 42), 66, "Esperado: 66") + self.assertEqual(suma(17, 13), 30, "Esperado: 30") + self.assertEqual(suma(-11, 6), -5, "Esperado: -5") + self.assertEqual(suma(0, 9), 9, "Esperado: 9") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q1_2 + :nocodelens: + + Escriba un programa que lea un valor en metros y lo muestre convertido a milimetros. |br| + + ~~~~ + def metros_a_milimetros(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(metros_a_milimetros(1), 1000,"Esperado: 1000") + self.assertEqual(metros_a_milimetros(0.2), 200,"Esperado: 200") + self.assertEqual(metros_a_milimetros(30), 30000,"Esperado: 30000") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q1_3 + :nocodelens: + + Escriba un programa que lea el número de días, horas, minutos y segundos del + usuario. Calcular el total en segundos. |br| + + ~~~~ + def tiempo_en_segundos(dias, horas, minutos, segundos): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(tiempo_en_segundos(2, 5, 2, 5), 190925, "Esperado: 190925") + self.assertEqual(tiempo_en_segundos(10, 89, 5, 0), 1184700, "Esperado: 1184700") + self.assertEqual(tiempo_en_segundos(8, 0, 2, 0), 691320, "Esperado: 691320") + self.assertEqual(tiempo_en_segundos(0, 5, 55, 6), 21306, "Esperado: 21306") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q1_4 + :nocodelens: + + Haz un programa que calcule un aumento de salario. Debe solicitar el + monto del salario y el porcentaje del aumento. Muestra el monto del + aumento y el nuevo salario. |br| + + ~~~~ + def aumento(salario, porcentaje): + #devolver los valores en una tupla como: return (aumento, nuevo_salario) + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(aumento(30500, 10), (3050, 33550), "Esperado: 3050 y 33550") + self.assertEqual(aumento(10400, 25), (2600, 13000), "Esperado: 2600 y 13000") + self.assertEqual(aumento(50100, 8), (4008, 54108), "Esperado: 4008 y 54108") + self.assertEqual(aumento(25000, 3), (750, 25750), "Esperado: 750 y 25750") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q1_5 + :nocodelens: + + Solicite el precio de un comerciante y el porcentaje de descuento. + Muestre el monto del descuento y el precio a pagar. |br| + + ~~~~ + def precio_con_descuento(precio, porcentaje): + #devolver los valores en una tupla como: return (descuento, precio_final) + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(precio_con_descuento(100100, 10), (10010, 90090), "Esperado: (10010,90090)") + self.assertEqual(precio_con_descuento(20523, 4), (820.92, 19702.08), "Esperado: (820.92,19702.08)") + self.assertEqual(precio_con_descuento(55566, 50), (27783, 27783), "Esperado: (27783,27783)") + self.assertEqual(precio_con_descuento(75660, 24), (18158.4, 57501.6), "Esperado: (18158.4,57501.6)") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q1_6 + :nocodelens: + + Calcule el tiempo de un viaje en auto. Pregunte por la distancia a recorrer + y la velocidad media esperada para el viaje. |br| + + ~~~~ + def tiempo(distancia, velocidad): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(tiempo(5, 5), 1, "Esperado: 1") + self.assertEqual(tiempo(100, 3), 100/3, "Esperado: " + str(100/3)) + self.assertEqual(tiempo(10500, 30), 350, "Esperado: 350") + self.assertEqual(tiempo(8600, 50), 172, "Esperado: 172") + self.assertEqual(tiempo(130, 200), 0.65, "Esperado: 0.65") + + + myTests().main() + + + .. tab:: Ejercicio 7 + + .. activecode:: q1_7 + :nocodelens: + + Convierta una temperatura escrita en Celsius a Fahrenheit. F = (9 * C) / 5 + 32 |br| + + ~~~~ + def celsius_a_fahrenheit(c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(celsius_a_fahrenheit(20), ((9 * 20) / 5) + 32, "Esperado: 68") + self.assertEqual(celsius_a_fahrenheit(68), ((9 * 68) / 5) + 32, "Esperado: 154.4") + self.assertEqual(celsius_a_fahrenheit(0), ((9 * 0) / 5) + 32, "Esperado: 32") + self.assertEqual(celsius_a_fahrenheit(-10), ((9 * -10) / 5) + 32, "Esperado: 14") + self.assertEqual(celsius_a_fahrenheit(-24), ((9 * -24) / 5) + 32, "Esperado: -11.2") + + + myTests().main() + + + .. tab:: Ejercicio 8 + + .. activecode:: q1_8 + :nocodelens: + + Ahora haga lo contrario, de Fahrenheit a Celsius. |br| + + ~~~~ + def fahrenheit_a_celsius(f): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(fahrenheit_a_celsius(21), ((21 - 32) * 5) / 9, "Esperado: " + str(((21 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_a_celsius(108), ((108 - 32) * 5) / 9, "Esperado: " + str(((108 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_a_celsius(0), ((0 - 32) * 5) / 9, "Esperado: " + str(((0 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_a_celsius(-10), ((-10 - 32) * 5) / 9, "Esperado: " + str(((-10 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_a_celsius(14), ((14 - 32) * 5) / 9, "Esperado: " + str(((14 - 32) * 5) / 9)) + + + myTests().main() + + + .. tab:: Ejercicio 9 + + .. activecode:: q1_9 + :nocodelens: + + Escriba un programa que pregunte por la cantidad de kilómetros recorridos + por un automóvil alquilado, así como el número de días que ha estado alquilado + el coche. Calcule el precio a pagar, sabiendo que el coche cuesta R $ 60,00 + por día y R $ 0,15 por km recorrido. |br| + + ~~~~ + def precio(km, dias): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(precio(123, 3), (0.15 * 123) + (60 * 3), "Esperado: " + str((0.15 * 123) + (60 * 3))) + self.assertEqual(precio(800, 4), (0.15 * 800) + (60 * 4), "Esperado: " + str((0.15 * 800) + (60 * 4))) + self.assertEqual(precio(60, 1), (0.15 * 60) + (60 * 1), "Esperado: " + str((0.15 * 60) + (60 * 1))) + self.assertEqual(precio(90, 2), (0.15 * 90) + (60 * 2), "Esperado: " + str((0.15 * 90) + (60 * 2))) + self.assertEqual(precio(1016, 7), (0.15 * 1016) + (60 * 7), "Esperado: " + str((0.15 * 1016) + (60 * 7))) + + + myTests().main() + + + .. tab:: Ejercicio 10 + + .. activecode:: q1_10 + :nocodelens: + + Escribe un programa para calcular la reducción en la vida útil de un fumador. + Preguntar cantidad de cigarrillos fumados por día y cuántos años ha fumado. + Considere que un fumador pierde 10 minutos de vida por cada cigarrillo, calcula + cuántos días de vida perderá un fumador. Mostrar los días totales. |br| + + ~~~~ + def fumador(cigarrillos, anios): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + fumador(10, 1), ((10 * 1 * 365) * 10) / 1440, "Esperado: " + str(((10 * 1 * 365) * 10) / 1440) + ) + self.assertEqual(fumador(3, 5), ((3 * 5 * 365) * 10) / 1440, "Esperado: " + str(((3 * 5 * 365) * 10) / 1440)) + self.assertEqual(fumador(1, 8), ((1 * 8 * 365) * 10) / 1440, "Esperado: " + str(((1 * 8 * 365) * 10) / 1440)) + self.assertEqual(fumador(2, 3), ((2 * 3 * 365) * 10) / 1440, "Esperado: " + str(((2 * 3 * 365) * 10) / 1440)) + + + myTests().main() + + + .. tab:: Ejercicio 11 + + .. activecode:: q1_11 + :nocodelens: + + Sabiendo que ``str()`` convierte valores numéricos en cadenas, + calcule cuántos dígitos hay en 2 elevados a un millón. |br| + + ~~~~ + def digitos(): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(digitos(), 301030, "Esperado: 301030") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz10.rst.txt b/293/_sources/quiz/Quiz10.rst.txt new file mode 100644 index 0000000000..a978f1d178 --- /dev/null +++ b/293/_sources/quiz/Quiz10.rst.txt @@ -0,0 +1,228 @@ +========= +Quiz - 10 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz10 + + .. tab:: Ejercicio 1 + + .. activecode:: q10_1 + :nocodelens: + + Desarrolle la función ``cuantas_donas`` que toma a ``n``, un número entero + positivo, como parámetro, y devuelve una cadena de forma ``"Número de donas: n"``, + donde ``n`` es el valor que se le pasó a la función como argumento. No obstante, + si ``n`` >= 10, ``cuantas_donas`` devolverá ``"muchas"`` en vez de ``n``. |br| |br| + Ejemplos: |br| + ``cuantas_donas(5)`` -> ``"Número de donas: 5"`` |br| + ``cuantas_donas(23)`` -> ``"Número de donas: muchas"`` |br| + + ~~~~ + def cuantas_donas(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(cuantas_donas(4), "Número de donas: 4", "Esperado: Número de donas: 4") + self.assertEqual(cuantas_donas(9), "Número de donas: 9", "Esperado: Número de donas: 9") + self.assertEqual( + cuantas_donas(10), + "Número de donas: muchas", + "Esperado: Número de donas: muchas", + ) + self.assertEqual( + cuantas_donas(99), + "Número de donas: muchas", + "Esperado: Número de donas: muchas", + ) + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q10_2 + :nocodelens: + + Desarrolla la función ``cadena_de_extremos`` que, dada una cadena ``s``, + devuelva una cadena con las dos primeras y las dos últimas letras de ``s``. + Sin embargo, si la cadena tiene menos de 2 letras, devuelve una cadena vacía. |br| |br| + Ejemplos: |br| + ``cadena_de_extremos("palmeras")`` -> ``"paas"`` |br| + ``cadena_de_extremos("a")`` -> ``""`` |br| + + ~~~~ + def cadena_de_extremos(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(cadena_de_extremos("palmeras"), "paas", "Esperado: paas") + self.assertEqual(cadena_de_extremos("algoritmos"), "alos", "Esperado: alos") + self.assertEqual(cadena_de_extremos("co"), "coco", "Esperado: coco") + self.assertEqual(cadena_de_extremos("a"), "", "Esperado: ''") + self.assertEqual(cadena_de_extremos("xyz"), "xyyz", "Esperado: xyyz") + self.assertEqual(cadena_de_extremos(""), "", "Esperado: ''") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q10_3 + :nocodelens: + + Desarrolle la función ``remplazar_primer_caracter`` que, dada una cadena ``s``, + devuelva una cadena en la que todas las apariciones del primer carácter en ``s`` + se reemplacen por "*", a excepción del primero. **Nota:** + use el método ``.replace(valor_a_replazar, nuevo_valor)`` para resolver el + ejercicio. |br| |br| + Ejemplos: |br| + ``remplazar_primer_caracter("google")`` -> ``"goo*le"`` |br| + ``remplazar_primer_caracter("dona")`` -> ``"dona"`` |br| + + ~~~~ + def remplazar_primer_caracter(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(remplazar_primer_caracter("babble"), "ba**le", "Esperado: ba**le") + self.assertEqual(remplazar_primer_caracter("aardvark"), "a*rdv*rk", "Esperado: a*rdv*rk") + self.assertEqual(remplazar_primer_caracter("google"), "goo*le", "Esperado: goo*le") + self.assertEqual(remplazar_primer_caracter("dona"), "dona", "Esperado: dona") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q10_4 + :nocodelens: + + Desarrolle la función ``combinar_dos_cadenas`` que tome dos cadenas como + argumentos, ``a`` y ``b``, y devuelva una nueva cadena de la siguiente forma: + + - La nueva cadena tiene que ser una combinación de ``a`` y ``b``. + - La nueva cadena tendrá la forma ``" "``, note el espacio entre ambas. + - La nueva cadena intercambiará las primeras dos letras de ``a`` y ``b``. + + Suponga que ``a`` y ``b`` tienen más de 2 caracteres. + Para mayor claridad, observe los siguientes ejemplos. |br| |br| + Ejemplos: |br| + ``combinar_dos_cadenas("mix", "pod")`` -> ``"pox mid"`` |br| + ``combinar_dos_cadenas("pezzy", "firm")`` -> ``"fizzy perm"`` |br| + + ~~~~ + def combinar_dos_cadenas(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(combinar_dos_cadenas("mix", "pod"), "pox mid", "Esperado: pox mid") + self.assertEqual(combinar_dos_cadenas("dog", "dinner"), "dig donner", "Esperado: dig donner") + self.assertEqual( + combinar_dos_cadenas("gnash", "sport"), + "spash gnort", + "Esperado: spash gnort", + ) + self.assertEqual(combinar_dos_cadenas("pezzy", "firm"), "fizzy perm", "Esperado: fizzy perm") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + + .. activecode:: q10_5 + :nocodelens: + + Desarrolle la función ``es_palindromo`` que toma una cadena ``s`` como + parámetro y verifica si ``s`` es palíndromo o no, devolviendo ``True`` o + ``False`` respectivamente. |br| |br| + Ejemplos: |br| + ``es_palindromo("asa")`` -> ``True`` |br| + ``es_palindromo("casa")`` -> ``False`` |br| + + ~~~~ + def es_palindromo(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(es_palindromo("asa"), True, "Esperado: True") + self.assertEqual(es_palindromo("casa"), False, "Esperado: False") + self.assertEqual(es_palindromo("reconocer"), True, "Esperado: True") + self.assertEqual(es_palindromo("palabra"), False, "Esperado: False") + self.assertEqual(es_palindromo("radar"), True, "Esperado: True") + self.assertEqual(es_palindromo("seres"), True, "Esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q10_6 + :nocodelens: + + Desarrolle la función ``contar_ocurrencias`` que toma dos parámetros: + ``frase`` y ``palabra``, ambos de tipo cadena. La función debe devolver + el número de veces que ``palabra`` se encuentra en ``frase``. |br| |br| + Ejemplos: |br| + ``contar_ocurrencias("a ana y a mariana les gustan las manzanas", "ana")`` -> ``3`` |br| + + ~~~~ + def contar_ocurrencias(frase, palabra): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + contar_ocurrencias("a ana y a mariana les gustan las manzanas", "ana"), + 3, + "Esperado: 3", + ) + self.assertEqual(contar_ocurrencias("Cats, rats, bats, and hats.", "ats"), 4, "Esperado: 4") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz10_en.rst.txt b/293/_sources/quiz/Quiz10_en.rst.txt new file mode 100644 index 0000000000..da72374b97 --- /dev/null +++ b/293/_sources/quiz/Quiz10_en.rst.txt @@ -0,0 +1,228 @@ +========= +Quiz - 10 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz10 + + .. tab:: Exercise 1 + + .. activecode:: q10_1_en + :nocodelens: + + Develop the function ``cuantas_donas`` that takes ``n``, a positive integer, as a parameter, + and returns a string in the form of ``"Number of donuts: n"``, where ``n`` is the value + passed to the function as an argument. However, if ``n`` >= 10, ``cuantas_donas`` will + return ``"many"`` instead of ``n``. |br| |br| + Examples: |br| + ``cuantas_donas(5)`` -> ``"Number of donuts: 5"`` |br| + ``cuantas_donas(23)`` -> ``"Number of donuts: many"`` |br| + + ~~~~ + def cuantas_donas(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(cuantas_donas(4), "Number of donuts: 4", "Expected output: Number of donuts: 4") + self.assertEqual(cuantas_donas(9), "Number of donuts: 9", "Expected output: Number of donuts: 9") + self.assertEqual( + cuantas_donas(10), + "Number of donuts: many", + "Expected output: Number of donuts: many", + ) + self.assertEqual( + cuantas_donas(99), + "Number of donuts: many", + "Expected output: Number of donuts: many", + ) + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q10_2_en + :nocodelens: + + Develop the function ``cadena_de_extremos`` that, given a string ``s``, + returns a string with the first two and last two letters of ``s``. + However, if the string has less than 2 letters, it returns an empty string. |br| |br| + Examples: |br| + ``cadena_de_extremos("palmeras")`` -> ``"paas"`` |br| + ``cadena_de_extremos("a")`` -> ``""`` |br| + + ~~~~ + def cadena_de_extremos(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(cadena_de_extremos("palmeras"), "paas", "Expected output: paas") + self.assertEqual(cadena_de_extremos("algoritmos"), "alos", "Expected output: alos") + self.assertEqual(cadena_de_extremos("co"), "coco", "Expected output: coco") + self.assertEqual(cadena_de_extremos("a"), "", "Expected output: ''") + self.assertEqual(cadena_de_extremos("xyz"), "xyyz", "Expected output: xyyz") + self.assertEqual(cadena_de_extremos(""), "", "Expected output: ''") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q10_3_en + :nocodelens: + + Develop the function ``remplazar_primer_caracter`` that, given a string ``s``, + returns a string in which all occurrences of the first character in ``s`` + are replaced by "*", except for the first one. **Note:** + use the method ``.replace(value_to_replace, new_value)`` to solve the + exercise. |br| |br| + Examples: |br| + ``remplazar_primer_caracter("google")`` -> ``"goo*le"`` |br| + ``remplazar_primer_caracter("dona")`` -> ``"dona"`` |br| + + ~~~~ + def remplazar_primer_caracter(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(remplazar_primer_caracter("babble"), "ba**le", "Expected output: ba**le") + self.assertEqual(remplazar_primer_caracter("aardvark"), "a*rdv*rk", "Expected output: a*rdv*rk") + self.assertEqual(remplazar_primer_caracter("google"), "goo*le", "Expected output: goo*le") + self.assertEqual(remplazar_primer_caracter("dona"), "dona", "Expected output: dona") + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: q10_4_en + :nocodelens: + + Develop the function ``combinar_dos_cadenas`` that takes two strings as + arguments, ``a`` and ``b``, and returns a new string in the following way: + + - The new string has to be a combination of ``a`` and ``b``. + - The new string will have the form ``"
"``, note the space between both. + - The new string will interchange the first two letters of ``a`` and ``b``. + + Suppose that ``a`` and ``b`` have more than 2 characters. + For better clarification, see the following examples. |br| |br| + Examples: |br| + ``combinar_dos_cadenas("mix", "pod")`` -> ``"pox mid"`` |br| + ``combinar_dos_cadenas("pezzy", "firm")`` -> ``"fizzy perm"`` |br| + + ~~~~ + def combinar_dos_cadenas(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(combinar_dos_cadenas("mix", "pod"), "pox mid", "Expected output: pox mid") + self.assertEqual(combinar_dos_cadenas("dog", "dinner"), "dig donner", "Expected output: dig donner") + self.assertEqual( + combinar_dos_cadenas("gnash", "sport"), + "spash gnort", + "Expected output: spash gnort", + ) + self.assertEqual(combinar_dos_cadenas("pezzy", "firm"), "fizzy perm", "Expected output: fizzy perm") + + + myTests().main() + + + .. tab:: Exercise 5 + + + .. activecode:: q10_5_en + :nocodelens: + + Develop the function ``es_palindromo`` that takes a string ``s`` as + parameter and checks if ``s`` is a palindrome or not, returning ``True`` or + ``False`` accordingly. |br| |br| + Examples: |br| + ``es_palindromo("asa")`` -> ``True`` |br| + ``es_palindromo("casa")`` -> ``False`` |br| + + ~~~~ + def es_palindromo(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(es_palindromo("asa"), True, "Expected output: True") + self.assertEqual(es_palindromo("casa"), False, "Expected output: False") + self.assertEqual(es_palindromo("reconocer"), True, "Expected output: True") + self.assertEqual(es_palindromo("palabra"), False, "Expected output: False") + self.assertEqual(es_palindromo("radar"), True, "Expected output: True") + self.assertEqual(es_palindromo("seres"), True, "Expected output: True") + + + myTests().main() + + + .. tab:: Exercise 6 + + .. activecode:: q10_6_en + :nocodelens: + + Develop the function ``contar_ocurrencias`` that takes two parameters: + ``frase`` and ``palabra``, both of type string. The function should return + the number of times that ``palabra`` occurs in ``frase``. |br| |br| + Examples: |br| + ``contar_ocurrencias("a ana y a mariana les gustan las manzanas", "ana")`` -> ``3`` |br| + + ~~~~ + def contar_ocurrencias(frase, palabra): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + contar_ocurrencias("a ana y a mariana les gustan las manzanas", "ana"), + 3, + "Expected output: 3", + ) + self.assertEqual(contar_ocurrencias("Cats, rats, bats, and hats.", "ats"), 4, "Expected output: 4") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz11.rst.txt b/293/_sources/quiz/Quiz11.rst.txt new file mode 100644 index 0000000000..bc7a152b5c --- /dev/null +++ b/293/_sources/quiz/Quiz11.rst.txt @@ -0,0 +1,253 @@ +========= +Quiz - 11 +========= + +.. |br| raw:: html + +
+ +.. tabbed:: quiz11 + + .. tab:: Ejercicio 1 + + .. activecode:: q11_1 + :nocodelens: + + Desarrolle la función ``verbo`` que recibe una cadena ``s`` como parámetro. Si la longitud de la cadena es al menos 3, debe devolver la cadena original concatenando ``"ing"`` al final. Si la cadena ``s`` ya termina en ``"ing"``, concatene la cadena ``"ly"``. Si la longitud de la cadena es menor que 3, devuelve la cadena original. |br| |br| + Ejemplos: |br| + ``verbo("singing")`` -> ``"singingly"`` |br| + ``verbo("travel")`` -> ``"traveling"`` |br| + ``verbo("do")`` -> ``"do"`` |br| + + ~~~~ + def verbo(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(verbo("hail"), "hailing", "Esperado: hailing") + self.assertEqual(verbo("swiming"), "swimingly", "Esperado: swimingly") + self.assertEqual(verbo("do"), "do", "Esperado: do") + self.assertEqual(verbo("singing"), "singingly", "Esperado: singingly") + self.assertEqual(verbo("travel"), "traveling", "Esperado: traveling") + self.assertEqual(verbo("lly"), "llying", "Esperado: llying") + self.assertEqual(verbo("ing"), "ingly", "Esperado: ingly") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q11_2 + :nocodelens: + + Desarrolle la función ``no_es_malo`` que recibe una cadena ``s`` como parámetro. La función debe buscar la primera aparición de la cadena ``"no es"`` y la última aparición de la cadena ``"malo"`` o la cadena ``"mala"``, si alguna de ellas aparece después de la primera, reemplace ``"no es" ... "malo"`` o ``"no es" ... "mala"`` por las cadenas ``"es bueno"`` o ``"es buena"`` respectivamente, luego devuelva el resultado. |br| |br| + Ejemplos: |br| + ``no_es_malo("El té no es malo")`` -> ``"El té es bueno"`` |br| + ``no_es_malo("La película no es mala")`` -> ``"La película es buena"`` |br| + ``no_es_malo("El precio de esta casa no es para nada malo")`` -> ``"El precio de esta casa es bueno"`` |br| + ``no_es_malo("El teléfono es malo")`` -> ``"El teléfono es malo"`` |br| + + ~~~~ + def no_es_malo(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + no_es_malo("El televisor no es malo"), + "El televisor es bueno", + "Esperado: El televisor es bueno" + ) + self.assertEqual( + no_es_malo("El asado de la cena no es malo!"), + "El asado de la cena es bueno!", + "Esperado: El asado de la cena es bueno!" + ) + self.assertEqual( + no_es_malo("El té no está caliente"), + "El té no está caliente", + "Esperado: El té no está caliente" + ) + self.assertEqual( + no_es_malo("La película no es mala"), + "La película es buena", + "Esperado: La película es buena" + ) + self.assertEqual(no_es_malo("no es para nada malo"), "es bueno", "Esperado: es bueno") + self.assertEqual(no_es_malo("no es malo"), "es bueno", "Esperado: es bueno") + self.assertEqual(no_es_malo("malo"), "malo", "Esperado: malo") + self.assertEqual(no_es_malo("no"), "no", "Esperado: no") + self.assertEqual(no_es_malo("NO"), "NO", "Esperado: NO") + self.assertEqual(no_es_malo("MALO"), "MALO", "Esperado: MALO") + self.assertEqual(no_es_malo("NO es MALO"), "NO es MALO", "Esperado: NO es MALO") + self.assertEqual(no_es_malo("no es MALO"), "no es MALO", "Esperado: no es MALO") + self.assertEqual(no_es_malo("NO es malo"), "NO es malo", "Esperado: NO es malo") + self.assertEqual(no_es_malo("no es malo ni mala"), "es buena", "Esperado: es buena") + self.assertEqual(no_es_malo("no es ni mala ni malo"), "es bueno", "Esperado: es bueno") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q11_3 + :nocodelens: + + Desarrolle la función ``inicio_final`` que recibe dos cadenas ``a`` y ``b``. Las cadenas tienen que ser dividas en dos, si alguna de las cadenas tiene un número impar de caracteres, la primera mitad será la subcadena más larga (por ejemplo ``perro`` se dividirá entre: ``per`` y ``ro``). Dada las dos cadenas, devuelva una nueva cadena formada de la siguiente manera ``a_inicio + b_inicio + a_final + b_final``. |br| |br| + Ejemplos: |br| + ``inicio_final("abcd", "1234")`` -> ``"ab12cd34"`` |br| + ``inicio_final("abc", "1234")`` -> ``"ab12c34"`` |br| + ``inicio_final("abc", "123")`` -> ``"ab12c3"`` |br| + + ~~~~ + def inicio_final(a, b): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(inicio_final("abcd", "xy"), "abxcdy", "Esperado: abxcdy") + self.assertEqual(inicio_final("abcde", "xyz"), "abcxydez", "Esperado: abcxydez") + self.assertEqual(inicio_final("a", "b"), "ab", "Esperado: ab") + self.assertEqual(inicio_final("ac", "b"), "abc", "Esperado: abc") + self.assertEqual(inicio_final("a", "bc"), "abc", "Esperado: abc") + self.assertEqual(inicio_final("", ""), "", "Esperado: ''") + self.assertEqual(inicio_final("a", ""), "a", "Esperado: 'a'") + self.assertEqual(inicio_final("", "b"), "b", "Esperado: 'b'") + self.assertEqual( + inicio_final("Kitten", "Donut"), + "KitDontenut", + "Esperado: KitDontenut" + ) + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q11_4 + :nocodelens: + + Desarrolle la función ``cuantos_ceros`` que dado un entero ``n`` positivo, devuelva la cantidad de ceros al final del entero ``n``. |br| |br| + Ejemplos: |br| + ``cuantos_ceros(10010)`` -> ``1`` |br| + ``cuantos_ceros(908007000)`` -> ``3`` |br| + + ~~~~ + def cuantos_ceros(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(cuantos_ceros(10100100010000), 4, "Esperado: 4") + self.assertEqual(cuantos_ceros(90000000000000000010), 1, "Esperado: 1") + self.assertEqual(cuantos_ceros(10), 1, "Esperado: 1") + self.assertEqual(cuantos_ceros(1050051222), 0, "Esperado: 0") + self.assertEqual(cuantos_ceros(1010101010), 1, "Esperado: 1") + self.assertEqual(cuantos_ceros(5000), 3, "Esperado: 3") + self.assertEqual(cuantos_ceros(10000000000), 10, "Esperado: 10") + self.assertEqual(cuantos_ceros(555), 0, "Esperado: 0") + self.assertEqual(cuantos_ceros(1), 0, "Esperado: 0") + self.assertEqual(cuantos_ceros(0), 0, "Esperado: 0") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q11_5 + :nocodelens: + + Desarrolle la función ``contar_2`` que recibe un entero ``n`` positivo mayor que 0. La función debe devolver la cantidad de veces que el dígito 2 aparece en el intervalo ``[0, n-1]``. |br| |br| + Ejemplos: |br| + ``contar_2(20)`` -> ``2`` |br| + ``contar_2(5)`` -> ``1`` |br| + ``contar_2(1)`` -> ``0`` |br| + + ~~~~ + def contar_2(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(contar_2(20), 2, "Esperado: 2") + self.assertEqual(contar_2(1), 0, "Esperado: 0") + self.assertEqual(contar_2(5), 1, "Esperado: 1") + self.assertEqual(contar_2(999), 300, "Esperado: 300") + self.assertEqual(contar_2(555), 216, "Esperado: 216") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q11_6 + :nocodelens: + + Desarrolle la función ``inicio_potencia`` que recibe un entero ``n`` positivo mayor que 0. La función debe devolver la primera potencia de 2 que comienza con ``n``. |br| |br| + Ejemplos: |br| + ``inicio_potencia(65)`` -> ``16`` |br| + *Explicación*: para ``n = 65`` la potencia ``2^16`` da como resultado ``65536`` que contiene a ``n`` al comienzo. |br| |br| + ``inicio_potencia(4)`` -> ``2`` |br| + *Explicación*: para ``n = 4`` la potencia ``2^2`` da como resultado ``4`` que contiene a ``n`` al comienzo. |br| |br| + ``inicio_potencia(3)`` -> ``5`` |br| + *Explicación*: para ``n = 3`` la potencia ``2^5`` da como resultado ``32`` que contiene a ``n`` al comienzo. |br| + + ~~~~ + def inicio_potencia(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(inicio_potencia(7), 46, "Esperado: 46") + self.assertEqual(inicio_potencia(3), 5, "Esperado: 5") + self.assertEqual(inicio_potencia(133), 316, "Esperado: 316") + self.assertEqual(inicio_potencia(1024), 10, "Esperado: 10") + self.assertEqual(inicio_potencia(123), 90, "Esperado: 90") + self.assertEqual(inicio_potencia(1), 0, "Esperado: 0") + self.assertEqual(inicio_potencia(10), 10, "Esperado: 10") + self.assertEqual(inicio_potencia(50), 102, "Esperado: 102") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz11_en.rst.txt b/293/_sources/quiz/Quiz11_en.rst.txt new file mode 100644 index 0000000000..85f1ee4c7e --- /dev/null +++ b/293/_sources/quiz/Quiz11_en.rst.txt @@ -0,0 +1,253 @@ +========= +Quiz - 11 +========= + +.. |br| raw:: html + +
+ +.. tabbed:: quiz11 + + .. tab:: Exercise 1 + + .. activecode:: q11_1_en + :nocodelens: + + Develop the function ``verbo`` that receives a string ``s`` as a parameter. If the length of the string is at least 3, it should return the original string concatenated with ``"ing"`` at the end. If the string ``s`` already ends with ``"ing"``, concatenate the string ``"ly"``. If the length of the string is less than 3, it returns the original string. |br| |br| + Examples: |br| + ``verbo("singing")`` -> ``"singingly"`` |br| + ``verbo("travel")`` -> ``"traveling"`` |br| + ``verbo("do")`` -> ``"do"`` |br| + + ~~~~ + def verbo(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(verbo("hail"), "hailing", "Expected: hailing") + self.assertEqual(verbo("swiming"), "swimingly", "Expected: swimingly") + self.assertEqual(verbo("do"), "do", "Expected: do") + self.assertEqual(verbo("singing"), "singingly", "Expected: singingly") + self.assertEqual(verbo("travel"), "traveling", "Expected: traveling") + self.assertEqual(verbo("lly"), "llying", "Expected: llying") + self.assertEqual(verbo("ing"), "ingly", "Expected: ingly") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q11_2_en + :nocodelens: + + Develop the function ``no_es_malo`` that receives a string ``s`` as a parameter. The function must search for the first occurrence of the string ``"no es"`` and the last occurrence of the string ``"malo"`` or the string ``"mala"``, if either appears after the first one, replace ``"no es" ... "malo"`` or ``"no es" ... "mala"`` with the strings ``"es bueno"`` or ``"es buena"`` respectively, then return the result. |br| |br| + Examples: |br| + ``no_es_malo("El té no es malo")`` -> ``"El té es bueno"`` |br| + ``no_es_malo("La película no es mala")`` -> ``"La película es buena"`` |br| + ``no_es_malo("El precio de esta casa no es para nada malo")`` -> ``"El precio de esta casa es bueno"`` |br| + ``no_es_malo("El teléfono es malo")`` -> ``"El teléfono es malo"`` |br| + + ~~~~ + def no_es_malo(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + no_es_malo("El televisor no es malo"), + "El televisor es bueno", + "Expected: El televisor es bueno" + ) + self.assertEqual( + no_es_malo("El asado de la cena no es malo!"), + "El asado de la cena es bueno!", + "Expected: El asado de la cena es bueno!" + ) + self.assertEqual( + no_es_malo("El té no está caliente"), + "El té no está caliente", + "Expected: El té no está caliente" + ) + self.assertEqual( + no_es_malo("La película no es mala"), + "La película es buena", + "Expected: La película es buena" + ) + self.assertEqual(no_es_malo("no es para nada malo"), "es bueno", "Expected: es bueno") + self.assertEqual(no_es_malo("no es malo"), "es bueno", "Expected: es bueno") + self.assertEqual(no_es_malo("malo"), "malo", "Expected: malo") + self.assertEqual(no_es_malo("no"), "no", "Expected: no") + self.assertEqual(no_es_malo("NO"), "NO", "Expected: NO") + self.assertEqual(no_es_malo("MALO"), "MALO", "Expected: MALO") + self.assertEqual(no_es_malo("NO es MALO"), "NO es MALO", "Expected: NO es MALO") + self.assertEqual(no_es_malo("no es MALO"), "no es MALO", "Expected: no es MALO") + self.assertEqual(no_es_malo("NO es malo"), "NO es malo", "Expected: NO es malo") + self.assertEqual(no_es_malo("no es malo ni mala"), "es buena", "Expected: es buena") + self.assertEqual(no_es_malo("no es ni mala ni malo"), "es bueno", "Expected: es bueno") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q11_3_en + :nocodelens: + + Develop the function ``inicio_final`` that receives two strings ``a`` and ``b``. The strings have to be divided into two, if either of the strings has an odd number of characters, the first half will be the longest substring (for example ``dog`` will be divided into: ``do`` and ``g``). Given the two strings, return a new string formed as follows ``a_start + b_start + a_end + b_end``. |br| |br| + Examples: |br| + ``inicio_final("abcd", "1234")`` -> ``"ab12cd34"`` |br| + ``inicio_final("abc", "1234")`` -> ``"ab12c34"`` |br| + ``inicio_final("abc", "123")`` -> ``"ab12c3"`` |br| + + ~~~~ + def inicio_final(a, b): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(inicio_final("abcd", "xy"), "abxcdy", "Expected: abxcdy") + self.assertEqual(inicio_final("abcde", "xyz"), "abcxydez", "Expected: abcxydez") + self.assertEqual(inicio_final("a", "b"), "ab", "Expected: ab") + self.assertEqual(inicio_final("ac", "b"), "abc", "Expected: abc") + self.assertEqual(inicio_final("a", "bc"), "abc", "Expected: abc") + self.assertEqual(inicio_final("", ""), "", "Expected: ''") + self.assertEqual(inicio_final("a", ""), "a", "Expected: 'a'") + self.assertEqual(inicio_final("", "b"), "b", "Expected: 'b'") + self.assertEqual( + inicio_final("Kitten", "Donut"), + "KitDontenut", + "Expected: KitDontenut" + ) + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: q11_4_en + :nocodelens: + + Develop the function ``cuantos_ceros`` that given a positive integer ``n``, returns the number of zeros at the end of the integer. |br| |br| + Examples: |br| + ``cuantos_ceros(10010)`` -> ``1`` |br| + ``cuantos_ceros(908007000)`` -> ``3`` |br| + + ~~~~ + def cuantos_ceros(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(cuantos_ceros(10100100010000), 4, "Expected: 4") + self.assertEqual(cuantos_ceros(90000000000000000010), 1, "Expected: 1") + self.assertEqual(cuantos_ceros(10), 1, "Expected: 1") + self.assertEqual(cuantos_ceros(1050051222), 0, "Expected: 0") + self.assertEqual(cuantos_ceros(1010101010), 1, "Expected: 1") + self.assertEqual(cuantos_ceros(5000), 3, "Expected: 3") + self.assertEqual(cuantos_ceros(10000000000), 10, "Expected: 10") + self.assertEqual(cuantos_ceros(555), 0, "Expected: 0") + self.assertEqual(cuantos_ceros(1), 0, "Expected: 0") + self.assertEqual(cuantos_ceros(0), 0, "Expected: 0") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q11_5_en + :nocodelens: + + Develop the function ``contar_2`` that receives a positive integer ``n`` greater than 0. The function must return the number of times the digit 2 appears in the interval``[0, n-1]``. |br| |br| + Examples: |br| + ``contar_2(20)`` -> ``2`` |br| + ``contar_2(5)`` -> ``1`` |br| + ``contar_2(1)`` -> ``0`` |br| + + ~~~~ + def contar_2(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(contar_2(20), 2, "Expected: 2") + self.assertEqual(contar_2(1), 0, "Expected: 0") + self.assertEqual(contar_2(5), 1, "Expected: 1") + self.assertEqual(contar_2(999), 300, "Expected: 300") + self.assertEqual(contar_2(555), 216, "Expected: 216") + + + myTests().main() + + + .. tab:: Exercise 6 + + .. activecode:: q11_6_en + :nocodelens: + + Develop the function ``inicio_potencia`` that receives a positive integer ``n`` greater than 0. The function must return the first power of 2 that starts with ``n``. |br| |br| + Examples: |br| + ``inicio_potencia(65)`` -> ``16`` |br| + *Explanation*: for ``n = 65`` the power of ``2^16`` results in ``65536`` which contains ``n`` at the beginning. |br| |br| + ``inicio_potencia(4)`` -> ``2`` |br| + *Explanation*: for ``n = 4`` the power of ``2^2`` results in ``4`` which contains ``n`` at the beginning. |br| |br| + ``inicio_potencia(3)`` -> ``5`` |br| + *Explanation*: for ``n = 3`` the power of ``2^5`` results in ``32`` which contains ``n`` at the beginning. |br| + + ~~~~ + def inicio_potencia(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(inicio_potencia(7), 46, "Expected: 46") + self.assertEqual(inicio_potencia(3), 5, "Expected: 5") + self.assertEqual(inicio_potencia(133), 316, "Expected: 316") + self.assertEqual(inicio_potencia(1024), 10, "Expected: 10") + self.assertEqual(inicio_potencia(123), 90, "Expected: 90") + self.assertEqual(inicio_potencia(1), 0, "Expected: 0") + self.assertEqual(inicio_potencia(10), 10, "Expected: 10") + self.assertEqual(inicio_potencia(50), 102, "Expected: 102") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz12.rst.txt b/293/_sources/quiz/Quiz12.rst.txt new file mode 100644 index 0000000000..87632f6ef8 --- /dev/null +++ b/293/_sources/quiz/Quiz12.rst.txt @@ -0,0 +1,123 @@ +========= +Quiz - 12 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz12 + + .. tab:: Ejercicio 1 + + .. activecode:: q12_1 + :nocodelens: + + Desarrolle la función ``terminan_igual`` que, dada una lista de cadenas ``palabras``, devuelva el número de cadenas + con longitud >= 2 donde el primer y último carácter son iguales. |br| |br| + Ejemplo: |br| + ``terminan_igual(["aba", "xyz", "aa", "x", "bbb"])`` -> ``3`` |br| + + ~~~~ + def terminan_igual(palabras): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(terminan_igual(["aba", "xyz", "aa", "x", "bbb"]), 3, "Esperado: 3") + self.assertEqual(terminan_igual(["", "x", "xy", "xyx", "xx"]), 2, "Esperado: 2") + self.assertEqual(terminan_igual(["aaa", "be", "abc", "hello"]), 1, "Esperado: 1") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q12_2 + :nocodelens: + + Desarrolle la función ``x_antes`` que, dada una lista de cadenas ``palabras``, devuelva + otra lista en la que todas las cadenas que comienzan con el carácter ``'x'`` sean los primeros elementos de la lista. + Después, el resto de palabras serán acomodadas según su orden alfabético. **Nota**: Recuerde + que ``sorted(lista)`` devuelve una lista ordenada. |br| |br| + Ejemplos: |br| + ``x_antes(["bbb", "ccc", "axx", "xzz", "xaa"])`` -> ``["xaa", "xzz", "axx", "bbb", "ccc"]`` |br| + ``x_antes(["ccc", "bbb", "aaa", "xcc", "xaa"])`` -> ``["xaa", "xcc", "aaa", "bbb", "ccc"]`` |br| + + ~~~~ + def x_antes(palabras): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + x_antes(["bbb", "ccc", "axx", "xzz", "xaa"]), + ["xaa", "xzz", "axx", "bbb", "ccc"], + "Esperado: ['xaa', 'xzz', 'axx', 'bbb', 'ccc']", + ) + self.assertEqual( + x_antes(["ccc", "bbb", "aaa", "xcc", "xaa"]), + ["xaa", "xcc", "aaa", "bbb", "ccc"], + "Esperado: ['xaa', 'xcc', 'aaa', 'bbb', 'ccc']", + ) + self.assertEqual( + x_antes(["mix", "xyz", "apple", "xanadu", "aardvark"]), + ["xanadu", "xyz", "aardvark", "apple", "mix"], + "Esperado: ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']", + ) + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q12_3 + :nocodelens: + + Desarrolle la función ``ordenar_tuplas`` que, dada una lista de tuplas no vacías, devuelve otra lista + de tuplas ordenada de forma ascendente tomando en cuenta el último elemento de cada tupla. |br| |br| + Ejemplos: |br| + ``ordenar_tuplas([(1, 3), (3, 2), (2, 1)])`` -> ``[(2, 1), (3, 2), (1, 3)]`` |br| + ``ordenar_tuplas([(2, 3), (1, 2), (3, 1)])`` -> ``[(3, 1), (1, 2), (2, 3)]`` |br| + + + + ~~~~ + def ordenar_tuplas(tuplas): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + ordenar_tuplas([(1, 3), (3, 2), (2, 1)]), [(2, 1), (3, 2), (1, 3)], "Esperado: [(2, 1), (3, 2), (1, 3)]" + ) + self.assertEqual( + ordenar_tuplas([(2, 3), (1, 2), (3, 1)]), [(3, 1), (1, 2), (2, 3)], "Esperado: [(3, 1), (1, 2), (2, 3)]" + ) + self.assertEqual( + ordenar_tuplas([(1, 7), (1, 3), (3, 4, 5), (2, 2)]), + [(2, 2), (1, 3), (3, 4, 5), (1, 7)], + "Esperado: [(2, 2), (1, 3), (3, 4, 5), (1, 7)]", + ) + + + myTests().main() diff --git a/293/_sources/quiz/Quiz12_en.rst.txt b/293/_sources/quiz/Quiz12_en.rst.txt new file mode 100644 index 0000000000..a17c665b03 --- /dev/null +++ b/293/_sources/quiz/Quiz12_en.rst.txt @@ -0,0 +1,123 @@ +========= +Quiz - 12 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz12 + + .. tab:: Exercise 1 + + .. activecode:: q12_1_en + :nocodelens: + + Develop the function ``ends_equal`` that, given a list of strings ``words``, returns the number of strings + with length >= 2 where the first and last character are the same. |br| |br| + Example: |br| + ``ends_equal(["aba", "xyz", "aa", "x", "bbb"])`` -> ``3`` |br| + + ~~~~ + def ends_equal(words): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(ends_equal(["aba", "xyz", "aa", "x", "bbb"]), 3, "Expected: 3") + self.assertEqual(ends_equal(["", "x", "xy", "xyx", "xx"]), 2, "Expected: 2") + self.assertEqual(ends_equal(["aaa", "be", "abc", "hello"]), 1, "Expected: 1") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q12_2_en + :nocodelens: + + Develop the function ``x_before`` that, given a list of strings ``words``, returns + another list in which all strings that start with the ``'x'`` character are the first elements of the list. + Then, the rest of the words will be arranged according to their alphabetical order. **Note**: Remember + that ``sorted(list)`` returns a sorted list. |br| |br| + Examples: |br| + ``x_before(["bbb", "ccc", "axx", "xzz", "xaa"])`` -> ``["xaa", "xzz", "axx", "bbb", "ccc"]`` |br| + ``x_before(["ccc", "bbb", "aaa", "xcc", "xaa"])`` -> ``["xaa", "xcc", "aaa", "bbb", "ccc"]`` |br| + + ~~~~ + def x_before(words): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + x_before(["bbb", "ccc", "axx", "xzz", "xaa"]), + ["xaa", "xzz", "axx", "bbb", "ccc"], + "Expected: ['xaa', 'xzz', 'axx', 'bbb', 'ccc']", + ) + self.assertEqual( + x_before(["ccc", "bbb", "aaa", "xcc", "xaa"]), + ["xaa", "xcc", "aaa", "bbb", "ccc"], + "Expected: ['xaa', 'xcc', 'aaa', 'bbb', 'ccc']", + ) + self.assertEqual( + x_before(["mix", "xyz", "apple", "xanadu", "aardvark"]), + ["xanadu", "xyz", "aardvark", "apple", "mix"], + "Expected: ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']", + ) + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q12_3_en + :nocodelens: + + Develop the function ``sort_tuples`` that, given a non-empty list of tuples, returns another list + of tuples sorted in ascending order taking into account the last element of each tuple. |br| |br| + Examples: |br| + ``sort_tuples([(1, 3), (3, 2), (2, 1)])`` -> ``[(2, 1), (3, 2), (1, 3)]`` |br| + ``sort_tuples([(2, 3), (1, 2), (3, 1)])`` -> ``[(3, 1), (1, 2), (2, 3)]`` |br| + + + + ~~~~ + def sort_tuples(tuples): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + sort_tuples([(1, 3), (3, 2), (2, 1)]), [(2, 1), (3, 2), (1, 3)], "Expected: [(2, 1), (3, 2), (1, 3)]" + ) + self.assertEqual( + sort_tuples([(2, 3), (1, 2), (3, 1)]), [(3, 1), (1, 2), (2, 3)], "Expected: [(3, 1), (1, 2), (2, 3)]" + ) + self.assertEqual( + sort_tuples([(1, 7), (1, 3), (3, 4, 5), (2, 2)]), + [(2, 2), (1, 3), (3, 4, 5), (1, 7)], + "Expected: [(2, 2), (1, 3), (3, 4, 5), (1, 7)]", + ) + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz13.rst.txt b/293/_sources/quiz/Quiz13.rst.txt new file mode 100644 index 0000000000..7211a55aea --- /dev/null +++ b/293/_sources/quiz/Quiz13.rst.txt @@ -0,0 +1,101 @@ +========= +Quiz - 13 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz13 + + .. tab:: Ejercicio 1 + + .. activecode:: q13_1 + :nocodelens: + + Desarrolle la función ``remover_iguales`` que recibe una lista ``numeros`` de enteros. La función debe devolver una lista sin los elementos repetidos y ordenados de manera ascendente. |br| |br| + Ejemplos: |br| + ``remover_iguales([1, 2, 2, 3])`` -> ``[1, 2, 3]`` |br| + ``remover_iguales([1, 2, 3])`` -> ``[1, 2, 3]`` |br| + ``remover_iguales([1, 2, 2, 1])`` -> ``[1, 2]`` |br| + + ~~~~ + def remover_iguales(numeros): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(remover_iguales([2, 2, 1, 3]), [1, 2, 3], "Esperado: [1, 2, 3]") + self.assertEqual(remover_iguales([2, 2, 3, 2, 3]), [2, 3], "Esperado: [2, 3]") + self.assertEqual(remover_iguales([-2, 2, 3, -2, 2]), [-2, 2, 3], "Esperado: [-2, 2, 3]") + self.assertEqual(remover_iguales([]), [], "Esperado: []") + self.assertEqual(remover_iguales([1, 2, 3, 4]), [1, 2, 3, 4], "Esperado: [1, 2, 3, 4]") + self.assertEqual(remover_iguales([1, 1, 1, 1]), [1], "Esperado: []") + self.assertEqual(remover_iguales([0, -1, 1, 3]), [-1, 0, 1, 3], "Esperado: [-1, 0, 1, 3]") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q13_2 + :nocodelens: + + Desarrolle la función ``encriptar`` que recibe una cadena ``frase``. La función debe devolver una nueva cadena encriptada, siguiendo las siguientes reglas: |br| + + 1. Se deben retirar todas las letras repetidas de cada una de las palabras de la frase. |br| + 2. Se deben ordenar las letras restantes de cada una de las palabras. |br| + + Ejemplo: |br| + ``encriptar("anita lava la tina")`` -> ``"aint alv al aint"`` |br| + *Consejo*: intente convertir la frase en una lista de palabras, luego intente ordenar las letras y construya una cadena con el resultado. |br| + + ~~~~ + def encriptar(frase): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + encriptar("ana e mariana gostam de banana"), + "an e aimnr agmost de abn", + "Esperado: an e aimnr agmost de abn", + ) + self.assertEqual( + encriptar("Batatinha quando nasce esparrama pelo chão"), + "Bahint adnoqu acens aemprs elop choã", + "Esperado: Bahint adnoqu acens aemprs elop choã", + ) + self.assertEqual( + encriptar("anita lava la tina"), + "aint alv al aint", "Esperado: aint alv al aint" + ) + self.assertEqual( + encriptar("¿Hola como estas?"), + "Halo¿ cmo ?aest", + "Esperado: Halo¿ cmo ?aest" + ) + self.assertEqual( + encriptar("ana puede venir mañana"), + "an depu einrv amnñ", + "Esperado: an depu einrv amnñ" + ) + self.assertEqual(encriptar("11111 2222 3333"), "1 2 3", "Esperado: 1 2 3") + self.assertEqual(encriptar("12345"), "12345", "Esperado: 12345") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz13_en.rst.txt b/293/_sources/quiz/Quiz13_en.rst.txt new file mode 100644 index 0000000000..870a3705f7 --- /dev/null +++ b/293/_sources/quiz/Quiz13_en.rst.txt @@ -0,0 +1,101 @@ +========= +Quiz - 13 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz13 + + .. tab:: Exercise 1 + + .. activecode:: q13_1_en + :nocodelens: + + Develop the function ``remove_duplicates`` that receives a list ``numbers`` of integers. The function should return a list without repeated elements and sorted in ascending order. |br| |br| + Examples: |br| + ``remove_duplicates([1, 2, 2, 3])`` -> ``[1, 2, 3]`` |br| + ``remove_duplicates([1, 2, 3])`` -> ``[1, 2, 3]`` |br| + ``remove_duplicates([1, 2, 2, 1])`` -> ``[1, 2]`` |br| + + ~~~~ + def remove_duplicates(numbers): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(remove_duplicates([2, 2, 1, 3]), [1, 2, 3], "Expected: [1, 2, 3]") + self.assertEqual(remove_duplicates([2, 2, 3, 2, 3]), [2, 3], "Expected: [2, 3]") + self.assertEqual(remove_duplicates([-2, 2, 3, -2, 2]), [-2, 2, 3], "Expected: [-2, 2, 3]") + self.assertEqual(remove_duplicates([]), [], "Expected: []") + self.assertEqual(remove_duplicates([1, 2, 3, 4]), [1, 2, 3, 4], "Expected: [1, 2, 3, 4]") + self.assertEqual(remove_duplicates([1, 1, 1, 1]), [1], "Expected: []") + self.assertEqual(remove_duplicates([0, -1, 1, 3]), [-1, 0, 1, 3], "Expected: [-1, 0, 1, 3]") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q13_2_en + :nocodelens: + + Develop the function ``encrypt`` that receives a string ``phrase``. The function should return a new encrypted string, following these rules: |br| + + 1. All repeated letters must be removed from each word of the phrase. |br| + 2. The remaining letters in each word must be sorted. |br| + + Example: |br| + ``encrypt("anita lava la tina")`` -> ``"aint alv al aint"`` |br| + *Tip*: try converting the phrase into a list of words, then try sorting the letters and build a string with the result. |br| + + ~~~~ + def encrypt(phrase): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + encrypt("ana e mariana gostam de banana"), + "an e aimnr agmost de abn", + "Expected: an e aimnr agmost de abn", + ) + self.assertEqual( + encrypt("Batatinha quando nasce esparrama pelo chão"), + "Bahint adnoqu acens aemprs elop choã", + "Expected: Bahint adnoqu acens aemprs elop choã", + ) + self.assertEqual( + encrypt("anita lava la tina"), + "aint alv al aint", "Expected: aint alv al aint" + ) + self.assertEqual( + encrypt("¿Hola como estas?"), + "Halo¿ cmo ?aest", + "Expected: Halo¿ cmo ?aest" + ) + self.assertEqual( + encrypt("ana puede venir mañana"), + "an depu einrv amnñ", + "Expected: an depu einrv amnñ" + ) + self.assertEqual(encrypt("11111 2222 3333"), "1 2 3", "Expected: 1 2 3") + self.assertEqual(encrypt("12345"), "12345", "Expected: 12345") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz1_en.rst.txt b/293/_sources/quiz/Quiz1_en.rst.txt new file mode 100644 index 0000000000..31f9a6274c --- /dev/null +++ b/293/_sources/quiz/Quiz1_en.rst.txt @@ -0,0 +1,322 @@ +======== +Quiz - 1 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz1 + + .. tab:: Exercise 1 + + .. activecode:: q1_1_en + :nocodelens: + + Make a program that asks for two integer numbers and prints the sum of those two numbers. |br| + + ~~~~ + def suma(n, m): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(suma(24, 42), 66, "Expected: 66") + self.assertEqual(suma(17, 13), 30, "Expected: 30") + self.assertEqual(suma(-11, 6), -5, "Expected: -5") + self.assertEqual(suma(0, 9), 9, "Expected: 9") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q1_2_en + :nocodelens: + + Write a program that reads a value in meters and shows it converted to millimeters. |br| + + ~~~~ + def metros_a_milimetros(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(metros_a_milimetros(1), 1000,"Expected: 1000") + self.assertEqual(metros_a_milimetros(0.2), 200,"Expected: 200") + self.assertEqual(metros_a_milimetros(30), 30000,"Expected: 30000") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q1_3_en + :nocodelens: + + Write a program that reads the number of days, hours, minutes, and seconds from + the user. Calculate the total number of seconds. |br| + + ~~~~ + def tiempo_en_segundos(dias, horas, minutos, segundos): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(tiempo_en_segundos(2, 5, 2, 5), 190925, "Expected: 190925") + self.assertEqual(tiempo_en_segundos(10, 89, 5, 0), 1184700, "Expected: 1184700") + self.assertEqual(tiempo_en_segundos(8, 0, 2, 0), 691320, "Expected: 691320") + self.assertEqual(tiempo_en_segundos(0, 5, 55, 6), 21306, "Expected: 21306") + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: q1_4_en + :nocodelens: + + Make a program that calculates a salary increase. It should request the + salary amount and the percentage of the increase. Display the amount of + the increase and the new salary. |br| + + ~~~~ + def aumento(salario, porcentaje): + #Return the values in a tuple like: return (increase, new_salary) + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(aumento(30500, 10), (3050, 33550), "Expected: (3050,33550)") + self.assertEqual(aumento(10400, 25), (2600, 13000), "Expected: (2600,13000)") + self.assertEqual(aumento(50100, 8), (4008, 54108), "Expected: (4008,54108)") + self.assertEqual(aumento(25000, 3), (750, 25750), "Expected: (750,25750)") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q1_5_en + :nocodelens: + + Request the price from a merchant and the percentage of the discount. + Display the discount amount and the final price. |br| + + ~~~~ + def precio_con_descuento(precio, porcentaje): + #Return the values in a tuple like: return (discount, final_price) + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(precio_con_descuento(100100, 10), (10010, 90090), "Expected: (10010,90090)") + self.assertEqual(precio_con_descuento(20523, 4), (820.92, 19702.08), "Expected: (820.92,19702.08)") + self.assertEqual(precio_con_descuento(55566, 50), (27783, 27783), "Expected: (27783,27783)") + self.assertEqual(precio_con_descuento(75660, 24), (18158.4, 57501.6), "Expected: (18158.4,57501.6)") + + + myTests().main() + + + .. tab:: Exercise 6 + + .. activecode:: q1_6_en + :nocodelens: + + Calculate the duration of a car trip. Ask for the distance to be covered + and the expected average speed for the trip. |br| + + ~~~~ + def duration(distance, speed): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(duration(5, 5), 1, "Expected: 1") + self.assertEqual(duration(100, 3), 100/3, "Expected: " + str(100/3)) + self.assertEqual(duration(10500, 30), 350, "Expected: 350") + self.assertEqual(duration(8600, 50), 172, "Expected: 172") + self.assertEqual(duration(130, 200), 0.65, "Expected: 0.65") + + + myTests().main() + + + .. tab:: Exercise 7 + + .. activecode:: q1_7_en + :nocodelens: + + Convert a temperature written in Celsius to Fahrenheit. F = (9 * C) / 5 + 32 |br| + + ~~~~ + def celsius_to_fahrenheit(c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(celsius_to_fahrenheit(20), ((9 * 20) / 5) + 32, "Expected: 68") + self.assertEqual(celsius_to_fahrenheit(68), ((9 * 68) / 5) + 32, "Expected: 154.4") + self.assertEqual(celsius_to_fahrenheit(0), ((9 * 0) / 5) + 32, "Expected: 32") + self.assertEqual(celsius_to_fahrenheit(-10), ((9 * -10) / 5) + 32, "Expected: 14") + self.assertEqual(celsius_to_fahrenheit(-24), ((9 * -24) / 5) + 32, "Expected: -11.2") + + + myTests().main() + + + .. tab:: Exercise 8 + + .. activecode:: q1_8_en + :nocodelens: + + Now do the opposite, from Fahrenheit to Celsius. |br| + + ~~~~ + def fahrenheit_to_celsius(f): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(fahrenheit_to_celsius(21), ((21 - 32) * 5) / 9, "Expected: " + str(((21 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_to_celsius(108), ((108 - 32) * 5) / 9, "Expected: " + str(((108 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_to_celsius(0), ((0 - 32) * 5) / 9, "Expected: " + str(((0 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_to_celsius(-10), ((-10 - 32) * 5) / 9, "Expected: " + str(((-10 - 32) * 5) / 9)) + self.assertEqual(fahrenheit_to_celsius(14), ((14 - 32) * 5) / 9, "Expected: " + str(((14 - 32) * 5) / 9)) + + + myTests().main() + + + .. tab:: Exercise 9 + + .. activecode:: q1_9_en + :nocodelens: + + Write a program that asks for the number of kilometers traveled + by a rented car, as well as the number of days the car has been rented for. + Calculate the price to be paid, knowing that the car costs R $ 60.00 + per day and R $ 0.15 per kilometer traveled. |br| + + ~~~~ + def price(km, days): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(price(123, 3), (0.15 * 123) + (60 * 3), "Expected: " + str((0.15 * 123) + (60 * 3))) + self.assertEqual(price(800, 4), (0.15 * 800) + (60 * 4), "Expected: " + str((0.15 * 800) + (60 * 4))) + self.assertEqual(price(60, 1), (0.15 * 60) + (60 * 1), "Expected: " + str((0.15 * 60) + (60 * 1))) + self.assertEqual(price(90, 2), (0.15 * 90) + (60 * 2), "Expected: " + str((0.15 * 90) + (60 * 2))) + self.assertEqual(price(1016, 7), (0.15 * 1016) + (60 * 7), "Expected: " + str((0.15 * 1016) + (60 * 7))) + + + myTests().main() + + + .. tab:: Exercise 10 + + .. activecode:: q1_10_en + :nocodelens: + + Write a program to calculate the reduction in the lifespan of a smoker. + Ask for the number of cigarettes smoked per day and how many years the person has smoked. + Consider that a smoker loses 10 minutes of life for each cigarette, calculate + how many days a smoker will lose. Show the total days. |br| + + ~~~~ + def smoker(cigarettes, years): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + smoker(10, 1), ((10 * 1 * 365) * 10) / 1440, "Expected: " + str(((10 * 1 * 365) * 10) / 1440) + ) + self.assertEqual(smoker(3, 5), ((3 * 5 * 365) * 10) / 1440, "Expected: " + str(((3 * 5 * 365) * 10) / 1440)) + self.assertEqual(smoker(1, 8), ((1 * 8 * 365) * 10) / 1440, "Expected: " + str(((1 * 8 * 365) * 10) / 1440)) + self.assertEqual(smoker(2, 3), ((2 * 3 * 365) * 10) / 1440, "Expected: " + str(((2 * 3 * 365) * 10) / 1440)) + + + myTests().main() + + + .. tab:: Exercise 11 + + .. activecode:: q1_11_en + :nocodelens: + + Knowing that ``str()`` converts numerical values to strings, + calculate how many digits there are in 2 raised to a million. |br| + + ~~~~ + def digits(): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(digits(), 301030, "Expected: 301030") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz2.rst.txt b/293/_sources/quiz/Quiz2.rst.txt new file mode 100644 index 0000000000..5a6bf3ea49 --- /dev/null +++ b/293/_sources/quiz/Quiz2.rst.txt @@ -0,0 +1,288 @@ +========= +Quiz - 2 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz2 + + .. tab:: Ejercicio 1 + + .. activecode:: q2_1 + :nocodelens: + + Desarrolle la función ``es_triangulo`` que recibe tres enteros positivos ``a``, ``b`` y ``c``. Éstos representan los lados de un triángulo. En la función debe verificar que con los parámetros dados se forma un triángulo. Si los parámetros dados forman un triángulo, la función debe devolver una cadena indicando su tipo, es decir, ``"Equilátero"``, ``"Isósceles"`` o ``"Escaleno"``, en caso contrario, la función debe devolver la cadena, ``"No es triángulo"``. |br| + **Nota**: recuerde que no es un triángulo cuando el lado de mayor longitud es mayor o igual que la suma de los otros dos. |br| |br| + Ejemplos: |br| + ``es_triangulo(2, 2, 2)`` -> ``"Equilátero"`` |br| + ``es_triangulo(3, 2, 2)`` -> ``"Isósceles"`` |br| + ``es_triangulo(4, 2, 6)`` -> ``"No es triángulo"`` |br| + ``es_triangulo(2, 1, 8)`` -> ``"No es triángulo"`` |br| + ~~~~ + def es_triangulo(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(es_triangulo(2, 2, 2), "Equilátero", "Esperado: Equilátero") + self.assertEqual(es_triangulo(2, 1, 2), "Isósceles", "Esperado: Isósceles") + self.assertEqual(es_triangulo(2, 1, 3), "No es triángulo", "Esperado: No es triángulo") + self.assertEqual(es_triangulo(2, 1, 8), "No es triángulo", "Esperado: No es triángulo") + self.assertEqual(es_triangulo(4, 2, 1), "No es triángulo", "Esperado: No es triángulo") + self.assertEqual(es_triangulo(4, 1000, 1000), "Isósceles", "Esperado: Isósceles") + self.assertEqual(es_triangulo(10000, 10000, 10000), "Equilátero", "Esperado: Equilátero") + self.assertEqual(es_triangulo(3, 2, 2), "Isósceles", "Esperado: Isósceles") + self.assertEqual(es_triangulo(10000, 1, 9999), "No es triángulo", "Esperado: No es triángulo") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q2_2 + :nocodelens: + + Desarrolle la función ``es_bisiesto`` que recibe el parámetro ``anio`` que es un entero positivo mayor que cero y representa un año. La función debe verificar si el parámetro dado es un año bisiesto, por lo tanto debe devolver ``True`` si lo es, o ``False`` en caso contrario. Un año es bisiesto, si es divisible entre 400 o también si es divisible entre 4 pero no divisible entre 100. |br| |br| + Ejemplos: |br| + ``es_bisiesto(2014)`` -> ``False`` |br| + ``es_bisiesto(2016)`` -> ``True`` |br| + ``es_bisiesto(1900)`` -> ``False`` |br| + ``es_bisiesto(2000)`` -> ``True`` |br| + ~~~~ + def es_bisiesto(anio): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(es_bisiesto(2000), True, "Esperado: True") + self.assertEqual(es_bisiesto(2001), False, "Esperado: False") + self.assertEqual(es_bisiesto(2020), True, "Esperado: True") + self.assertEqual(es_bisiesto(2016), True, "Esperado: True") + self.assertEqual(es_bisiesto(2400), True, "Esperado: True") + self.assertEqual(es_bisiesto(1952), True, "Esperado: True") + self.assertEqual(es_bisiesto(1900), False, "Esperado: False") + self.assertEqual(es_bisiesto(2200), False, "Esperado: False") + self.assertEqual(es_bisiesto(2100), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q2_3 + :nocodelens: + + Juan Pablo el pescador, es un buen hombre que trabaja todos los días de la semana. Al final de cada día de trabajo, Juan debe reportar al estado. Cada vez que trae un peso de pescado mayor al establecido por la normativa de pesca (50 kilogramos) debe pagar una multa de 4.00 unidades por kilogramo adicional. Para llevar un registro, él compro una computadora para controlar los ingresos de su trabajo y te solicitó que hicieras la función llamada ``generar_reporte`` que recibe una lista de flotantes positivos ``pesos``, que representan la cantidad que pescó Juan cada día de la semana. La función debe devolver un arreglo de tuplas, donde cada tupla debe ser un par de la forma ``(adicional, multa)``, que representan la cantidad de kilogramos adicional que pescó Juan durante un día y la multa que tuvo que pagar respectivamente. De no haber pagado multa el resultado será ``0.0`` en ambos casos. |br| |br| + Ejemplos: |br| + ``generar_reporte([25.5, 50.5, 60.25, 15, 100, 50, 30.50])`` -> ``[(0.0, 0.0), (0.5, 2.0), (10.25, 41.0), (0.0, 0.0), (50.0, 200.0), (0.0, 0.0),`` |br| ``(0.0, 0.0)]`` + ~~~~ + def generar_reporte(pesos): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + generar_reporte([25.5, 50.5, 60.25, 15.0, 100.0, 50.0, 30.50]), + [(0.0, 0.0), (0.5, 2.0), (10.25, 41.0), (0.0, 0.0), (50.0, 200.0), (0.0, 0.0), (0.0, 0.0)], + "Esperado: [(0.0, 0.0), (0.5, 2.0), (10.25, 41.0), (0.0, 0.0), (50.0, 200.0), (0.0, 0.0), (0.0, 0.0)]", + ) + self.assertEqual( + generar_reporte([5.55, 50.0, 10.25, 15.0, 0.0, 50.0, 51.0]), + [(0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (1.0, 4.0)], + "Esperado: [(0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (1.0, 4.0)]", + ) + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q2_4 + :nocodelens: + + Desarrolle la función ``mayor_tres`` que recibe tres números enteros ``a``, ``b`` y ``c``. La función debe devolver el mayor de los tres números, sin usar las funciones ``max`` o ``min``. |br| |br| + Ejemplos: |br| + ``mayor_tres(5, 2, 3)`` -> ``5`` |br| + ``mayor_tres(-5, 0, -2)`` -> ``0`` |br| + ~~~~ + def mayor_tres(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(mayor_tres(1, 2, 3), 3, "Esperado: 3") + self.assertEqual(mayor_tres(9, 2, 3), 9, "Esperado: 9") + self.assertEqual(mayor_tres(-9, 2, 1), 2, "Esperado: 2") + self.assertEqual(mayor_tres(1, 1, 1), 1, "Esperado: 1") + self.assertEqual(mayor_tres(5, 5, 4), 5, "Esperado: 5") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q2_5 + :nocodelens: + + Desarrolle la función ``mayor_menor_tres`` que recibe tres números enteros ``a``, ``b`` y ``c``. La función debe devolver una tupla de la forma ``(mayor, menor)`` que representan el mayor y el menor de los tres números, sin usar las funciones ``max`` o ``min``. |br| |br| + Ejemplos: |br| + ``mayor_menor_tres(5, 2, 3)`` -> ``(2, 5)`` |br| + ``mayor_menor_tres(-5, 0, -2)`` -> ``(-2, 0)`` |br| + ~~~~ + def mayor_menor_tres(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(mayor_menor_tres(1, 2, 3), (1, 3), "Esperado: (1, 3)") + self.assertEqual(mayor_menor_tres(9, 2, 3), (2, 9), "Esperado: (2, 9)") + self.assertEqual(mayor_menor_tres(-9, 2, 1), (-9, 2), "Esperado: (-9, 2)") + self.assertEqual(mayor_menor_tres(1, 1, 1), (1, 1), "Esperado: (1, 1)") + self.assertEqual(mayor_menor_tres(5, 5, 4), (4, 5), "Esperado: (4, 5)") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q2_6 + :nocodelens: + + Un trabajador de una empresa recibe un salario mensual bruto calculado por la cantidad de horas trabajadas multiplicada por su valor. De este ``salario_bruto`` se le descuentan al mes el ``11%`` por impuestos, el ``8%`` de seguro médico y ``5%`` como pago al sindicato. Desarrolle la función ``calcular_salario`` que recibe un flotante ``valor_hora`` y un entero ``cantidad_horas`` que representan cuánto gana por hora y la cantidad de horas trabajadas durante el mes. La función debe devolver un diccionario de la forma: |br| + + ``{"salario_bruto": A, "impuestos": B,`` |br| ``"seguro_medico": C, "sindicato": E, "salario_neto": F}``. |br| + + Donde A, B, C y D representan la cantidad de dinero correspondiente para cada ítem. |br| |br| + Ejemplos: |br| + ``calcular_salario(15.0, 120)`` -> ``{"salario_bruto": 1800.00, "impuestos": 198.00,`` |br| ``"seguro_medico": 144.0, "sindicato": 90.0, "salario_neto": 1368.00}``. |br| + ~~~~ + def calcular_salario(valor_hora, cantidad_horas): + + + ==== + from unittest.gui import TestCaseGui + import random + + + class myTests(TestCaseGui): + def get_expected_dictionary(self, salary): + result = { + "salario_bruto": salary, + "impuestos": salary * 0.11, + "seguro_medico": salary * 0.08, + "sindicato": salary * 0.05, + } + result["salario_neto"] = (salary - result["impuestos"] - + result["seguro_medico"] - result["sindicato"]) + return result + + def testOne(self): + test_numbers = 10 + min_hour = 50 + max_hour = 200 + min_price_hour = 7 + max_price_hour = 30 + for test in range(test_numbers): + hour = random.randint(min_hour, max_hour) + price = round(random.uniform(min_price_hour, max_price_hour), 2) + salary = price * hour + expected = self.get_expected_dictionary(salary) + result = calcular_salario(price, hour) + current_test = test + 1 + + self.assertEqual( + round(result["salario_bruto"], 2), + round(expected["salario_bruto"], 2), + f"Test #{current_test} - Salario Bruto esperado: {round(expected['salario_bruto'], 2)}", + ) + self.assertEqual( + round(result["impuestos"], 2), + round(expected["impuestos"], 2), + f"Test #{current_test} - Impuestos esperado: {round(expected['impuestos'], 2)}", + ) + self.assertEqual( + round(result["seguro_medico"], 2), + round(expected["seguro_medico"], 2), + f"Test #{current_test} - Seguro médico esperado: {round(expected['seguro_medico'], 2)}", + ) + self.assertEqual( + round(result["sindicato"], 2), + round(expected["sindicato"], 2), + f"Test #{current_test} - Sindicato esperado: {round(expected['sindicato'], 2)}", + ) + self.assertEqual( + round(result["salario_neto"], 2), + round(expected["salario_neto"], 2), + f"Test #{current_test} - Salario neto esperado: {round(expected['salario_neto'], 2)}", + ) + + + myTests().main() + + + .. tab:: Ejercicio 7 + + .. activecode:: q2_7 + :nocodelens: + + La pintura que venden en su ferretería de confianza tiene una cobertura de 1 litro por cada 3 metros cuadrados y la pintura se vende solo en botes de 18 litros que cuestan cada uno ``80.00`` unidades. Desarrolle la función ``puedo_pintar`` que recibe una cantidad en metros cuadrados de un área a pintar como un entero positivo ``area``. La función debe devolver una tupla con las cantidad de botes de pintura que se necesitan comprar para cubrir toda el área, así como su precio total, es decir, utilizando la forma ``(cantidad_botes, precio_total)``. |br| + **Nota**: solo se vende un número entero de botes de pintura. |br| |br| + Ejemplos: |br| + ``puedo_pintar(10)`` -> ``(1, 80.00)`` |br| + ``puedo_pintar(100)`` -> ``(2, 160.00)`` |br| + ``puedo_pintar(54)`` -> ``(1, 80.00)`` |br| + ``puedo_pintar(55)`` -> ``(2, 160.00)`` |br| + ~~~~ + def puedo_pintar(area): + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(puedo_pintar(10), (1, 80.00), "Esperado: (1, 80.00)") + self.assertEqual(puedo_pintar(100), (2, 160.00), "Esperado: (2, 160.00)") + self.assertEqual(puedo_pintar(54), (1, 80.00), "Esperado: (1, 80.00)") + self.assertEqual(puedo_pintar(55), (2, 160.00), "Esperado: (2, 160.00)") + self.assertEqual(puedo_pintar(1000), (19, 1520.00), "Esperado: (19, 1520.00)") + self.assertEqual(puedo_pintar(500), (10, 800.00), "Esperado: (10, 800.00)") + self.assertEqual(puedo_pintar(250), (5, 400.00), "Esperado: (5, 400.00)") + self.assertEqual(puedo_pintar(125), (3, 240.00), "Esperado: (3, 240.00)") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz2_en.rst.txt b/293/_sources/quiz/Quiz2_en.rst.txt new file mode 100644 index 0000000000..6fba826f3c --- /dev/null +++ b/293/_sources/quiz/Quiz2_en.rst.txt @@ -0,0 +1,289 @@ +========= +Quiz - 2 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz2 + + .. tab:: Exercise 1 + + .. activecode:: q2_1_en + :nocodelens: + + Develop the function ``es_triangulo`` that receives three positive integers ``a``, ``b``, and ``c``. They represent the sides of a triangle. The function should verify that a triangle is formed with the given parameters. If the given parameters form a triangle, the function should return a string indicating its type, i.e., ``"Equilátero"``, ``"Isósceles"``, or ``"Escaleno"``, otherwise, the function should return the string, ``"No es triángulo"``.|br| + **Note**: remember that it is not a triangle when the longest side is greater than or equal to the sum of the other two. |br| |br| + Examples: |br| + ``es_triangulo(2, 2, 2)`` -> ``"Equilátero"`` |br| + ``es_triangulo(3, 2, 2)`` -> ``"Isósceles"`` |br| + ``es_triangulo(4, 2, 6)`` -> ``"No es triángulo"`` |br| + ``es_triangulo(2, 1, 8)`` -> ``"No es triángulo"`` |br| + ~~~~ + def es_triangulo(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(es_triangulo(2, 2, 2), "Equilátero", "Expected: Equilátero") + self.assertEqual(es_triangulo(2, 1, 2), "Isósceles", "Expected: Isósceles") + self.assertEqual(es_triangulo(2, 1, 3), "No es triángulo", "Expected: No es triángulo") + self.assertEqual(es_triangulo(2, 1, 8), "No es triángulo", "Expected: No es triángulo") + self.assertEqual(es_triangulo(4, 2, 1), "No es triángulo", "Expected: No es triángulo") + self.assertEqual(es_triangulo(4, 1000, 1000), "Isósceles", "Expected: Isósceles") + self.assertEqual(es_triangulo(10000, 10000, 10000), "Equilátero", "Expected: Equilátero") + self.assertEqual(es_triangulo(3, 2, 2), "Isósceles", "Expected: Isósceles") + self.assertEqual(es_triangulo(10000, 1, 9999), "No es triángulo", "Expected: No es triángulo") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q2_2_en + :nocodelens: + + Develop the function ``es_bisiesto`` that receives the parameter ``anio`` which is a positive integer greater than zero and represents a year. The function should verify if the given parameter is a leap year, therefore, it should return ``True`` if it is, or ``False`` otherwise. A year is a leap year if it is divisible by 400, or also if it is divisible by 4 but not divisible by 100. |br| |br| + Examples: |br| + ``es_bisiesto(2014)`` -> ``False`` |br| + ``es_bisiesto(2016)`` -> ``True`` |br| + ``es_bisiesto(1900)`` -> ``False`` |br| + ``es_bisiesto(2000)`` -> ``True`` |br| + ~~~~ + def es_bisiesto(anio): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(es_bisiesto(2000), True, "Expected: True") + self.assertEqual(es_bisiesto(2001), False, "Expected: False") + self.assertEqual(es_bisiesto(2020), True, "Expected: True") + self.assertEqual(es_bisiesto(2016), True, "Expected: True") + self.assertEqual(es_bisiesto(2400), True, "Expected: True") + self.assertEqual(es_bisiesto(1952), True, "Expected: True") + self.assertEqual(es_bisiesto(1900), False, "Expected: False") + self.assertEqual(es_bisiesto(2200), False, "Expected: False") + self.assertEqual(es_bisiesto(2100), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q2_3_en + :nocodelens: + + Juan Pablo the fisherman, is a good man who works every day of the week. At the end of each work day, Juan must report to the state. Every time he brings a weight of fish greater than established by fishing regulations (50 kilograms) he must pay a fine of 4.00 units per additional kilogram. To keep track, he bought a computer to monitor his work income and asked you to make the function called `generate_report` that receives a list of positive floats `weights`, which represent the amount that Juan fished each day of the week. The function should return an array of tuples, where each tuple should be a pair of the form `(additional, fine)`, which represent the amount of additional kilograms that Juan fished during a day and the fine he had to pay respectively. If he did not pay a fine, the result will be `0.0` in both cases. |br| |br| + Examples: |br| + ``generate_report([25.5, 50.5, 60.25, 15, 100, 50, 30.50])`` -> ``[(0.0, 0.0), (0.5, 2.0), (10.25, 41.0), (0.0, 0.0), (50.0, 200.0), (0.0, 0.0), (0.0, 0.0)]`` + ~~~~ + def generate_report(weights): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + generate_report([25.5, 50.5, 60.25, 15.0, 100.0, 50.0, 30.50]), + [(0.0, 0.0), (0.5, 2.0), (10.25, 41.0), (0.0, 0.0), (50.0, 200.0), (0.0, 0.0), (0.0, 0.0)], + "Expected: [(0.0, 0.0), (0.5, 2.0), (10.25, 41.0), (0.0, 0.0), (50.0, 200.0), (0.0, 0.0), (0.0, 0.0)]", + ) + self.assertEqual( + generate_report([5.55, 50.0, 10.25, 15.0, 0.0, 50.0, 51.0]), + [(0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (1.0, 4.0)], + "Expected: [(0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (1.0, 4.0)]", + ) + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: q2_4_en + :nocodelens: + + Develop the function ``mayor_tres`` that receives three integers ``a``, ``b`` and ``c``. The function must return the highest of the three numbers, without using the functions ``max`` or ``min``. |br| |br| + Examples: |br| + ``mayor_tres(5, 2, 3)`` -> ``5`` |br| + ``mayor_tres(-5, 0, -2)`` -> ``0`` |br| + ~~~~ + def mayor_tres(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(mayor_tres(1, 2, 3), 3, "Expected: 3") + self.assertEqual(mayor_tres(9, 2, 3), 9, "Expected: 9") + self.assertEqual(mayor_tres(-9, 2, 1), 2, "Expected: 2") + self.assertEqual(mayor_tres(1, 1, 1), 1, "Expected: 1") + self.assertEqual(mayor_tres(5, 5, 4), 5, "Expected: 5") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q2_5_en + :nocodelens: + + Develop the function ``mayor_menor_tres`` that receives three integers ``a``, ``b`` and ``c``. The function must return a tuple of the form ``(mayor, menor)`` that represent the highest and the lowest of the three numbers, without using the functions ``max`` or ``min``. |br| |br| + Examples: |br| + ``mayor_menor_tres(5, 2, 3)`` -> ``(2, 5)`` |br| + ``mayor_menor_tres(-5, 0, -2)`` -> ``(-2, 0)`` |br| + ~~~~ + def mayor_menor_tres(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(mayor_menor_tres(1, 2, 3), (1, 3), "Expected: (1, 3)") + self.assertEqual(mayor_menor_tres(9, 2, 3), (2, 9), "Expected: (2, 9)") + self.assertEqual(mayor_menor_tres(-9, 2, 1), (-9, 2), "Expected: (-9, 2)") + self.assertEqual(mayor_menor_tres(1, 1, 1), (1, 1), "se Esperado: (1, 1)") + self.assertEqual(mayor_menor_tres(5, 5, 4), (4, 5), "Expected: (4, 5)") + + + myTests().main() + + + .. tab:: Exercise 6 + + .. activecode:: q2_6_en + :nocodelens: + + An employee of a company receives a monthly gross salary calculated by the amount of hours worked multiplied by its value. From this ``salary``, the month's ``11%`` for taxes, ``8%`` for health insurance, and ``5%`` for payment to the union are deducted. Develop the function ``calcular_salario`` that receives a float ``valor_hora`` and an integer ``cantidad_horas`` that represent how much he earns per hour and the amount of hours worked during the month. The function must return a dictionary of the form: |br| + + ``{"salario_bruto": A, "impuestos": B,`` |br| ``"seguro_medico": C, "sindicato": E, "salario_neto": F}``. |br| + + Where A, B, C, and D represent the amount of money corresponding to each item. |br| |br| + Examples: |br| + ``calcular_salario(15.0, 120)`` -> ``{"salario_bruto": 1800.00, "impuestos": 198.00,`` |br| ``"seguro_medico": 144.0, "sindicato": 90.0, "salario_neto": 1368.00}``. |br| + ~~~~ + def calcular_salario(valor_hora, cantidad_horas): + + + ==== + from unittest.gui import TestCaseGui + import random + + + class myTests(TestCaseGui): + def get_expected_dictionary(self, salary): + result = { + "salario_bruto": salary, + "impuestos": salary * 0.11, + "seguro_medico": salary * 0.08, + "sindicato": salary * 0.05, + } + result["salario_neto"] = (salary - result["impuestos"] - + result["seguro_medico"] - result["sindicato"]) + return result + + def testOne(self): + test_numbers = 10 + min_hour = 50 + max_hour = 200 + min_price_hour = 7 + max_price_hour = 30 + for test in range(test_numbers): + hour = random.randint(min_hour, max_hour) + price = round(random.uniform(min_price_hour, max_price_hour), 2) + salary = price * hour + expected = self.get_expected_dictionary(salary) + result = calcular_salario(price, hour) + current_test = test + 1 + + self.assertEqual( + round(result["salario_bruto"], 2), + round(expected["salario_bruto"], 2), + f"Test #{current_test} - Expected gross salary: {round(expected['salario_bruto'], 2)}", + ) + self.assertEqual( + round(result["impuestos"], 2), + round(expected["impuestos"], 2), + f"Test #{current_test} - Expected taxes: {round(expected['impuestos'], 2)}", + ) + self.assertEqual( + round(result["seguro_medico"], 2), + round(expected["seguro_medico"], 2), + f"Test #{current_test} - Expected health insurance: {round(expected['seguro_medico'], 2)}", + ) + self.assertEqual( + round(result["sindicato"], 2), + round(expected["sindicato"], 2), + f"Test #{current_test} - Expected union payment: {round(expected['sindicato'], 2)}", + ) + self.assertEqual( + round(result["salario_neto"], 2), + round(expected["salario_neto"], 2), + f"Test #{current_test} - Expected net salary: {round(expected['salario_neto'], 2)}", + ) + + + myTests().main() + + + .. tab:: Exercise 7 + + .. activecode:: q2_7_en + :nocodelens: + + The paint sold at your trusted hardware store has a coverage of 1 liter per every 3 square meters and the paint is sold only in cans of 18 liters that cost each one ``80.00`` units. Develop the function ``puedo_pintar`` that receives an amount in square meters of an area to be painted as a positive integer ``area``. The function should return a tuple with the amount of cans of paint that need to be bought to cover the entire area, as well as their total price, that is, using the form ``(amount_cans, total_price)``. |br| + **Note**: only an integer number of cans of paint is sold. |br| |br| + Examples: |br| + ``puedo_pintar(10)`` -> ``(1, 80.00)`` |br| + ``puedo_pintar(100)`` -> ``(2, 160.00)`` |br| + ``puedo_pintar(54)`` -> ``(1, 80.00)`` |br| + ``puedo_pintar(55)`` -> ``(2, 160.00)`` |br| + + ~~~~ + def puedo_pintar(area): + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(puedo_pintar(10), (1, 80.00), "Expected: (1, 80.00)") + self.assertEqual(puedo_pintar(100), (2, 160.00), "Expected: (2, 160.00)") + self.assertEqual(puedo_pintar(54), (1, 80.00), "Expected: (1, 80.00)") + self.assertEqual(puedo_pintar(55), (2, 160.00), "Expected: (2, 160.00)") + self.assertEqual(puedo_pintar(1000), (19, 1520.00), "Expected: (19, 1520.00)") + self.assertEqual(puedo_pintar(500), (10, 800.00), "Expected: (10, 800.00)") + self.assertEqual(puedo_pintar(250), (5, 400.00), "Expected: (5, 400.00)") + self.assertEqual(puedo_pintar(125), (3, 240.00), "Expected: (3, 240.00)") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz3.rst.txt b/293/_sources/quiz/Quiz3.rst.txt new file mode 100644 index 0000000000..2b1cf29ed1 --- /dev/null +++ b/293/_sources/quiz/Quiz3.rst.txt @@ -0,0 +1,168 @@ +======== +Quiz - 3 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz3 + + .. tab:: Ejercicio 1 + + .. activecode:: q3_1 + :nocodelens: + + Decimos que un número natural es triangular si es el producto de tres números naturales consecutivos. |br| |br| + Ejemplo: 120 es triangular, ya que 4 x 5 x 6 = 120. Dado un número entero no negativo ``n``, verifique si ``n`` es triangular. + Devuelva ``True`` si el número es triangular o ``False`` si no lo es. |br| + + ~~~~ + def triangular(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(triangular(24), True, "Esperado: True") + self.assertEqual(triangular(7), False, "Esperado: False") + self.assertEqual(triangular(10), True, "Esperado: True") + self.assertEqual(triangular(23), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q3_2 + :nocodelens: + + Indique cómo se debe devolver un cambio utilizando un número mínimo de billetes. + Su algoritmo debe leer el monto de la factura a pagar, ``cobro``, y el monto + del pago realizado, ``pago``, sin tener en cuenta los centavos. |br| + Suponga que los billetes para el cambio son 50, 20, 10, 5, 2 y 1, y que ninguno de ellos falta en la caja registradora. + Devuelva una lista con la cantidad de cada billete que represente el cambio. |br| + El primer elemento de la lista coincide con la cantidad 50, + el siguiente con 20, y así sucesivamente hasta 1. (El mismo orden que se muestra arriba). |br| |br| + Ejemplos: |br| + ``calcular_cambio(50, 100)`` -> [1,0,0,0,0,0] |br| + ``calcular_cambio(92, 100)`` -> [0,0,0,1,1,1] |br| + + ~~~~ + def calcular_cambio(cobro, pago): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(calcular_cambio(50, 100), [1,0,0,0,0,0], "Esperado: [1,0,0,0,0,0]") + self.assertEqual(calcular_cambio(61, 100), [0,1,1,1,2,0], "Esperado: [0,1,1,1,2,0]") + self.assertEqual(calcular_cambio(92, 100), [0,0,0,1,1,1], "Esperado: [0,0,0,1,1,1]") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q3_3 + :nocodelens: + + Compruebe que un número entero positivo ``n`` sea primo. |br| + Devuelva ``True`` si es primo o ``False`` si no lo es. |br| + + ~~~~ + def es_primo(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(es_primo(2), True, "Esperado: True") + self.assertEqual(es_primo(49), False, "Esperado: False") + self.assertEqual(es_primo(541), True, "Esperado: True") + self.assertEqual(es_primo(8831), True, "Esperado: True") + self.assertEqual(es_primo(7952), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q3_4 + :nocodelens: + + Dado un número entero positivo ``n``, determine su descomposición en factores primos + calculando también la multiplicidad de cada factor. + Devuelve un diccionario con las claves como primos y sus respectivos valores como la + frecuencia del primo en la factorización primaria del número. |br| |br| + Ejemplos: |br| + ``factores(5)`` -> {5:1} |br| + ``factores(420)`` -> {2:2, 3:1, 5:1, 7:1} |br| + + ~~~~ + def factores(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(factores(5), {5:1}, "Esperado: {5:1}") + self.assertEqual(factores(84), {2:2, 3:1, 7:1}, "Esperado: {2:2, 3:1, 7:1}") + self.assertEqual(factores(123), {3:1, 41:1}, "Esperado: {3:1, 41:1}") + self.assertEqual(factores(81), {3:4}, "Esperado: {3:4}") + self.assertEqual(factores(420), {2:2, 3:1, 5:1, 7:1}, "Esperado: {2:2, 3:1, 5:1, 7:1}") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q3_5 + :nocodelens: + + Haga un programa que solicite un número entero positivo ``n`` y lo muestre invertido. + Por ejemplo: 1234 genera 4321. Devuelve el número invertido. |br| |br| + Ejemplos: |br| + ``invertir_numero(123456789)`` -> 987654321 |br| + ``invertir_numero(1000)`` -> 1 |br| + + ~~~~ + def invertir_numero(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(invertir_numero(123), 321, "Esperado: 321") + self.assertEqual(invertir_numero(123456789), 987654321, "Esperado: 987654321") + self.assertEqual(invertir_numero(1001), 1001, "Esperado: 1001") + self.assertEqual(invertir_numero(1000), 1, "Esperado: 1") + self.assertEqual(invertir_numero(230), 32, "Esperado: 32") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz3_en.rst.txt b/293/_sources/quiz/Quiz3_en.rst.txt new file mode 100644 index 0000000000..b3a3cc187a --- /dev/null +++ b/293/_sources/quiz/Quiz3_en.rst.txt @@ -0,0 +1,168 @@ +======== +Quiz - 3 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz3 + + .. tab:: Exercise 1 + + .. activecode:: q3_1_en + :nocodelens: + + We say that a natural number is triangular if it is the product of three consecutive natural numbers. |br| |br| + Example: 120 is triangular, since 4 x 5 x 6 = 120. Given a non-negative integer ``n``, check if ``n`` is triangular. + Return ``True`` if the number is triangular or ``False`` if it is not. |br| + + ~~~~ + def triangular(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(triangular(24), True, "Expected: True") + self.assertEqual(triangular(7), False, "Expected: False") + self.assertEqual(triangular(10), True, "Expected: True") + self.assertEqual(triangular(23), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q3_2_en + :nocodelens: + + Indicate how to make change using the minimum number of bills. + Your algorithm should read the amount of the bill to be paid, ``cobro``, and the amount + paid, ``pago``, without taking into account the cents. |br| + Suppose the bills for change are 50, 20, 10, 5, 2 and 1, and that none of them is missing in the cash register. + Return a list with the quantity of each bill that represents the change. |br| + The first element of the list matches the quantity of 50, + the next with 20, and so on until 1. (The same order as shown above). |br| |br| + Examples: |br| + ``calculate_change(50, 100)`` -> [1,0,0,0,0,0] |br| + ``calculate_change(92, 100)`` -> [0,0,0,1,1,1] |br| + + ~~~~ + def calculate_change(cobro, pago): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(calculate_change(50, 100), [1,0,0,0,0,0], "Expected: [1,0,0,0,0,0]") + self.assertEqual(calculate_change(61, 100), [0,1,1,1,2,0], "Expected: [0,1,1,1,2,0]") + self.assertEqual(calculate_change(92, 100), [0,0,0,1,1,1], "Expected: [0,0,0,1,1,1]") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q3_3_en + :nocodelens: + + Check whether a positive integer ``n`` is prime. |br| + Return ``True`` if it is prime or ``False`` if it is not. |br| + + ~~~~ + def is_prime(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(is_prime(2), True, "Expected: True") + self.assertEqual(is_prime(49), False, "Expected: False") + self.assertEqual(is_prime(541), True, "Expected: True") + self.assertEqual(is_prime(8831), True, "Expected: True") + self.assertEqual(is_prime(7952), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: q3_4_en + :nocodelens: + + Given a positive integer ``n``, determine its prime factorization + also calculating the multiplicity of each factor. + Return a dictionary with the keys as primes and their respective values as the + frequency of the prime in the prime factorization of the number. |br| |br| + Examples: |br| + ``factors(5)`` -> {5:1} |br| + ``factors(420)`` -> {2:2, 3:1, 5:1, 7:1} |br| + + ~~~~ + def factors(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(factors(5), {5:1}, "Expected: {5:1}") + self.assertEqual(factors(84), {2:2, 3:1, 7:1}, "Expected: {2:2, 3:1, 7:1}") + self.assertEqual(factors(123), {3:1, 41:1}, "Expected: {3:1, 41:1}") + self.assertEqual(factors(81), {3:4}, "Expected: {3:4}") + self.assertEqual(factors(420), {2:2, 3:1, 5:1, 7:1}, "Expected: {2:2, 3:1, 5:1, 7:1}") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q3_5_en + :nocodelens: + + Make a program that asks for a positive integer ``n`` and shows it inverted. + For example: 1234 generates 4321. Return the inverted number. |br| |br| + Examples: |br| + ``invert_number(123456789)`` -> 987654321 |br| + ``invert_number(1000)`` -> 1 |br| + + ~~~~ + def invert_number(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(invert_number(123), 321, "Expected: 321") + self.assertEqual(invert_number(123456789), 987654321, "Expected: 987654321") + self.assertEqual(invert_number(1001), 1001, "Expected: 1001") + self.assertEqual(invert_number(1000), 1, "Expected: 1") + self.assertEqual(invert_number(230), 32, "Expected: 32") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz4.rst.txt b/293/_sources/quiz/Quiz4.rst.txt new file mode 100644 index 0000000000..512cf480d0 --- /dev/null +++ b/293/_sources/quiz/Quiz4.rst.txt @@ -0,0 +1,209 @@ +========= +Quiz - 4 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz4 + + .. tab:: Ejercicio 1 + + .. activecode:: q4_1 + :nocodelens: + + Desarrolle la función ``valores_extremos`` que tome el parámetro ``numeros``, que representa una lista de **10** números aleatorios entre 0-100. + La función debe devolver una tupla ``(a, b)``, donde a y b son el valor máximo y el mínimo respectivamente de la lista ``numeros``. Resuelva el problema sin usar + las funciones ``max`` ni ``min``. |br| |br| + Ejemplo: |br| + ``valores_extremos([15, 48, 0, 27, 13, 62, 32, 57, 85, 18])`` -> ``(85, 0)`` |br| + + ~~~~ + def valores_extremos(numeros): + + + ==== + from unittest.gui import TestCaseGui + from random import sample + + + class myTests(TestCaseGui): + def testOne(self): + numeros = sample(range(100), 10) + self.assertEqual( + valores_extremos(numeros), (max(numeros), min(numeros)), f"Esperado: ({max(numeros)}, {min(numeros)})" + ) + + def testTwo(self): + numeros = sample(range(100), 10) + self.assertEqual( + valores_extremos(numeros), (max(numeros), min(numeros)), f"Esperado: ({max(numeros)}, {min(numeros)})" + ) + + def testThree(self): + numeros = sample(range(100), 10) + self.assertEqual( + valores_extremos(numeros), (max(numeros), min(numeros)), f"Esperado: ({max(numeros)}, {min(numeros)})" + ) + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q4_2 + :nocodelens: + + Desarrolle la función ``pares_e_impares`` que toma a ``numeros`` como parámetro. ``numeros`` representa una lista de **20** números aleatorios entre 1-100. + La función debe devolver una tupla de listas de la forma ``([par], [impar])``, donde par e impar sean listas de números pares e impares que se encuentran + en ``numeros``, respectivamente. |br| |br| + + ~~~~ + def pares_e_impares(numeros): + + + ==== + from unittest.gui import TestCaseGui + from random import sample + + + class myTests(TestCaseGui): + def testOne(self): + numeros = sample(range(1, 100), 20) + self.assertEqual( + pares_e_impares(numeros), + ([n for n in numeros if n % 2 == 0], [n for n in numeros if n % 2 != 0]), + f"Esperado: ({[n for n in numeros if n%2 == 0]}, {[n for n in numeros if n%2 != 0]})", + ) + + def testTwo(self): + numeros = sample(range(1, 100), 20) + self.assertEqual( + pares_e_impares(numeros), + ([n for n in numeros if n % 2 == 0], [n for n in numeros if n % 2 != 0]), + f"Esperado: ({[n for n in numeros if n%2 == 0]}, {[n for n in numeros if n%2 != 0]})", + ) + + def testThree(self): + numeros = sample(range(1, 100), 20) + self.assertEqual( + pares_e_impares(numeros), + ([n for n in numeros if n % 2 == 0], [n for n in numeros if n % 2 != 0]), + f"Esperado: ({[n for n in numeros if n%2 == 0]}, {[n for n in numeros if n%2 != 0]})", + ) + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q4_3 + :nocodelens: + + Desarrolle la función ``intercalar_listas`` que toma dos parámetros, ``l1`` y ``l2``, representando listas de **10** números aleatorios entre 1-100. + La función debe generar una tercer lista compuesta de los elementos de ``l1`` y ``l2`` intercalados. Esta tercera lista será devuelta. |br| |br| + Ejemplo: |br| + ``intercalar_listas([1, 3, 5, .....], [2, 4, 6, ....])`` -> ``[1, 2, 3, 4, 5, 6, ....]`` |br| + + ~~~~ + def intercalar_listas(l1, l2): + + + ==== + from unittest.gui import TestCaseGui + from random import sample + + + class myTests(TestCaseGui): + def testOne(self): + l1 = sample(range(100), 10) + l2 = sample(range(100), 10) + self.assertEqual( + intercalar_listas(l1, l2), + [val for pair in zip(l1, l2) for val in pair], + f"Esperado: {[val for pair in zip(l1, l2) for val in pair]}", + ) + + def testTwo(self): + l1 = sample(range(100), 10) + l2 = sample(range(100), 10) + self.assertEqual( + intercalar_listas(l1, l2), + [val for pair in zip(l1, l2) for val in pair], + f"Esperado: {[val for pair in zip(l1, l2) for val in pair]}", + ) + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q4_4 + :nocodelens: + + A la función ``buscar_palabras`` se le pasará como argumento el siguiente ``texto``: |br| + *"The Python Software Foundation and the global Python community welcome and encourage participation by everyone. Our community is based on + mutual respect, tolerance, and encouragement, and we are working to help each other live up to these principles. We want our community to be more diverse: whoever you are, and + whatever your background, we welcome you."* |br| + Lo que debe hacer es generar una lista de palabras de este texto utilizando ``split()``. Después debe crear una lista de palabras que comienzan o + terminan con alguna de las letras en la cadena ``"python"``. Esta lista es la que será devuelta. **Nota**: No olvide primero eliminar los caracteres + especiales y tenga cuidado con las mayúsculas. |br| |br| + + ~~~~ + def buscar_palabras(texto): + + + ==== + + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + text = """The Python Software Foundation and the global Python community welcome and + encourage participation by everyone. Our community is based on mutual respect, tolerance, and encouragement, + and we are working to help each other live up to these principles. We want our community to be more diverse: + whoever you are, and whatever your background, we welcome you.""" + res = [ + word + for word in text.lower().replace(".", "").replace(",", "").split() + if word[0] in "python" or word[-1] in "python" + ] + self.assertEqual(buscar_palabras(text), res, f"Esperado: {res}") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q4_5 + :nocodelens: + + Ahora va a desarrollar la función ``buscar_palabras_2``, a la que se le pasará el texto anterior como parámetro. Una vez más va a separar el + texto en palabras, justo como lo hizo en el *Ejercicio 4*. Esta vez, debe calcular el número de palabras dentro de ``texto`` que tienen alguna + de las letras de la cadena ``"python"``, y además tienen una longitud mayor a 4 caracteres. |br| |br| + + ~~~~ + def buscar_palabras_2(texto): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + text = """The Python Software Foundation and the global Python community welcome and + encourage participation by everyone. Our community is based on mutual respect, tolerance, and encouragement, + and we are working to help each other live up to these principles. We want our community to be more diverse: + whoever you are, and whatever your background, we welcome you.""" + self.assertEqual(buscar_palabras_2(text), 24, "Esperado: 24") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz4_en.rst.txt b/293/_sources/quiz/Quiz4_en.rst.txt new file mode 100644 index 0000000000..7b8dd26aa4 --- /dev/null +++ b/293/_sources/quiz/Quiz4_en.rst.txt @@ -0,0 +1,209 @@ +========= +Quiz - 4 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz4 + + .. tab:: Exercise 1 + + .. activecode:: q4_1_en + :nocodelens: + + Develop the function ``valores_extremos`` which takes the parameter ``numeros``, representing a list of **10** random numbers between 0-100. + The function should return a tuple ``(a, b)``, where a and b are the maximum and minimum values respectively of the ``numeros`` list. Solve the problem without using + the functions ``max`` nor ``min``. |br| |br| + Example: |br| + ``valores_extremos([15, 48, 0, 27, 13, 62, 32, 57, 85, 18])`` -> ``(85, 0)`` |br| + + ~~~~ + def valores_extremos(numeros): + + + ==== + from unittest.gui import TestCaseGui + from random import sample + + + class myTests(TestCaseGui): + def testOne(self): + numeros = sample(range(100), 10) + self.assertEqual( + valores_extremos(numeros), (max(numeros), min(numeros)), f"Expected: ({max(numeros)}, {min(numeros)})" + ) + + def testTwo(self): + numeros = sample(range(100), 10) + self.assertEqual( + valores_extremos(numeros), (max(numeros), min(numeros)), f"Expected: ({max(numeros)}, {min(numeros)})" + ) + + def testThree(self): + numeros = sample(range(100), 10) + self.assertEqual( + valores_extremos(numeros), (max(numeros), min(numeros)), f"Expected: ({max(numeros)}, {min(numeros)})" + ) + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q4_2_en + :nocodelens: + + Develop the function ``pares_e_impares`` which takes the parameter ``numeros``. ``numeros`` represents a list of **20** random numbers between 1-100. + The function should return a tuple of lists of the form ``([even], [odd])``, where even and odd are lists of even and odd numbers that are + in ``numeros``, respectively. |br| |br| + + ~~~~ + def pares_e_impares(numeros): + + + ==== + from unittest.gui import TestCaseGui + from random import sample + + + class myTests(TestCaseGui): + def testOne(self): + numeros = sample(range(1, 100), 20) + self.assertEqual( + pares_e_impares(numeros), + ([n for n in numeros if n % 2 == 0], [n for n in numeros if n % 2 != 0]), + f"Expected: ({[n for n in numeros if n%2 == 0]}, {[n for n in numeros if n%2 != 0]})", + ) + + def testTwo(self): + numeros = sample(range(1, 100), 20) + self.assertEqual( + pares_e_impares(numeros), + ([n for n in numeros if n % 2 == 0], [n for n in numeros if n % 2 != 0]), + f"Expected: ({[n for n in numeros if n%2 == 0]}, {[n for n in numeros if n%2 != 0]})", + ) + + def testThree(self): + numeros = sample(range(1, 100), 20) + self.assertEqual( + pares_e_impares(numeros), + ([n for n in numeros if n % 2 == 0], [n for n in numeros if n % 2 != 0]), + f"Expected: ({[n for n in numeros if n%2 == 0]}, {[n for n in numeros if n%2 != 0]})", + ) + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q4_3_en + :nocodelens: + + Develop the function ``intercalar_listas`` which takes two parameters, ``l1`` and ``l2``, representing lists of **10** random numbers between 1-100. + The function should generate a third list composed of the elements of ``l1`` and ``l2`` interleaved. This third list will be returned. |br| |br| + Example: |br| + ``intercalar_listas([1, 3, 5, .....], [2, 4, 6, ....])`` -> ``[1, 2, 3, 4, 5, 6, ....]`` |br| + + ~~~~ + def intercalar_listas(l1, l2): + + + ==== + from unittest.gui import TestCaseGui + from random import sample + + + class myTests(TestCaseGui): + def testOne(self): + l1 = sample(range(100), 10) + l2 = sample(range(100), 10) + self.assertEqual( + intercalar_listas(l1, l2), + [val for pair in zip(l1, l2) for val in pair], + f"Expected: {[val for pair in zip(l1, l2) for val in pair]}", + ) + + def testTwo(self): + l1 = sample(range(100), 10) + l2 = sample(range(100), 10) + self.assertEqual( + intercalar_listas(l1, l2), + [val for pair in zip(l1, l2) for val in pair], + f"Expected: {[val for pair in zip(l1, l2) for val in pair]}", + ) + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: q4_4_en + :nocodelens: + + The function ``buscar_palabras`` will be passed the following ``texto`` as argument: |br| + *"The Python Software Foundation and the global Python community welcome and encourage participation by everyone. Our community is based on + mutual respect, tolerance, and encouragement, and we are working to help each other live up to these principles. We want our community to be more diverse: whoever you are, and + whatever your background, we welcome you."* |br| + It should generate a list of words from this text using ``split()``. Then it should create a list of words that start or end with any + of the letters in the string ``"python"``. This list is the one that will be returned. **Note**: Don't forget to first remove special characters + and be careful with capitalization. |br| |br| + + ~~~~ + def buscar_palabras(texto): + + + ==== + + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + text = """The Python Software Foundation and the global Python community welcome and + encourage participation by everyone. Our community is based on mutual respect, tolerance, and encouragement, + and we are working to help each other live up to these principles. We want our community to be more diverse: + whoever you are, and whatever your background, we welcome you.""" + res = [ + word + for word in text.lower().replace(".", "").replace(",", "").split() + if word[0] in "python" or word[-1] in "python" + ] + self.assertEqual(buscar_palabras(text), res, f"Expected: {res}") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q4_5_en + :nocodelens: + + Now you will develop the function ``buscar_palabras_2``, which will be passed the previous text as a parameter. Again you will separate the + text into words, just like you did in *Exercise 4*. This time, you should calculate the number of words within ``texto`` that have any + of the letters in the string ``"python"``, and also have a length greater than 4 characters. |br| |br| + + ~~~~ + def buscar_palabras_2(texto): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + text = """The Python Software Foundation and the global Python community welcome and + encourage participation by everyone. Our community is based on mutual respect, tolerance, and encouragement, + and we are working to help each other live up to these principles. We want our community to be more diverse: + whoever you are, and whatever your background, we welcome you.""" + self.assertEqual(buscar_palabras_2(text), 24, "Expected: 24") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz5.rst.txt b/293/_sources/quiz/Quiz5.rst.txt new file mode 100644 index 0000000000..b435761072 --- /dev/null +++ b/293/_sources/quiz/Quiz5.rst.txt @@ -0,0 +1,275 @@ +======== +Quiz - 5 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz5_1 + + .. tab:: Ejercicio 1_1 + + .. clickablearea:: q5_1 + :question: El siguiente programa declara una variable en el lugar equivocado del código. Su tarea es seleccionar la declaración incorrecta y seleccionar la línea correcta donde debería ir. + :iscode: + :feedback: Recuerda, que no puedes usar una variable sin haberla declarado anteriormente. + + :click-incorrect:x = 2:endclick: + :click-correct: :endclick: + :click-incorrect:si y > 8 entonces::endclick: + :click-correct:y = 5:endclick: + :click-incorrect:y = y * 2:endclick: + + :click-incorrect:en caso contrario::endclick: + :click-incorrect:x = x * 2::endclick: + :click-incorrect:imprime (x + y)::endclick: + + + .. tab:: Ejercicio 1_2 + + .. activecode:: q5_2 + :nocodelens: + + Traduzca el programa anterior (con la declaración en el lugar correcto) al lenguaje Python utilizando el siguiente bloque de código. |br| + ~~~~ + + ==== + + + .. tab:: Ejercicio 1_3 + + .. fillintheblank:: q5_3 + + ¿Qué imprime el programa anterior? + + - :9: Tu respuesta es correcta, ¡buen trabajo! + :.*: Tu respuesta es incorrecta, intenta nuevamente. + + +.. tabbed:: quiz5_2 + + .. tab:: Ejercicio 2_1 + + .. code-block:: none + + para i = 1 hasta 9: + si i != 3 entonces: + para j = 1 hasta 6: + imprimir("Hola") + + + .. tab:: Ejercicio 2_2 + + .. activecode:: q5_4 + :nocodelens: + + Traduzca el programa anterior al lenguaje Python utilizando el siguiente bloque de código. |br| + **Nota**: en nuestro pseudolenguaje, el ciclo incluye los extremos, es decir, 1 a 4 significa 1, 2, 3, 4. |br| + ~~~~ + + ==== + + + .. tab:: Ejercicio 2_3 + + .. fillintheblank:: q5_5 + + ¿Cuántas veces el programa anterior imprime ``"Hola"``? + + - :48: Tu respuesta es correcta, ¡buen trabajo! + :.*: Tu respuesta es incorrecta, intenta nuevamente. + + +.. tabbed:: quiz5_3 + + .. tab:: Ejercicio 3_1 + + .. activecode:: q5_6 + :nocodelens: + + Desarrolle la función ``pares_divisibles_7`` que recibe como parámetros dos enteros positivos, ``inicio`` y ``fin`` que representan el inicio y el fin de un intervalo de números, la función tiene que devolver la cantidad de números que son pares y también divisibles por 7. |br| |br| + Ejemplos: |br| + ``pares_divisibles_7(1, 7)`` -> ``0`` |br| + ``pares_divisibles_7(25, 123)`` -> ``7`` |br| + ``pares_divisibles_7(13, 245)`` -> ``17`` |br| + + ~~~~ + def pares_divisibles_7(inicio, fin): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(pares_divisibles_7(1, 7), 0, "Esperado: 0") + self.assertEqual(pares_divisibles_7(25, 123), 7, "Esperado: 7") + self.assertEqual(pares_divisibles_7(13, 245), 17, "Esperado: 17") + self.assertEqual(pares_divisibles_7(1300, 2460), 83, "Esperado: 83") + self.assertEqual(pares_divisibles_7(1, 2460), 175, "Esperado: 175") + + + myTests().main() + + + .. tab:: Ejercicio 3_2 + + .. fillintheblank:: q5_7 + + Utilice la función creada en el ejercicio anterior para responder ¿Cuántos números son pares y también divisibles por 7 entre 1067 y 3627 (inclusive)? + + - :183: Tu respuesta es correcta, ¡buen trabajo! + :.*: Tu respuesta es incorrecta, intenta nuevamente. + + +.. tabbed:: quiz5_4 + + .. tab:: Ejercicio 4_1 + + .. activecode:: q5_8 + :nocodelens: + + Daniela es una persona muy supersticiosa. Para ella, un número tiene **suerte** si contiene el dígito ``2`` pero no el ``7``. Ella además es muy curiosa y está interesada en saber ¿cuántos números de la suerte hay en un intervalo de números (incluido los extremos)?. Para ello le ha solicitado a usted que haga la función llamada ``cuantos_tienen_suerte``, que recibe como parámetros dos enteros positivos, ``inicio`` y ``fin`` que representan el inicio y el fin de un intervalo de números, la función tiene que devolver la cantidad de números que tienen **suerte**. |br| |br| + Ejemplos: |br| + ``cuantos_tienen_suerte(1, 7)`` -> ``1`` |br| + ``cuantos_tienen_suerte(1, 20)`` -> ``3`` |br| + ``cuantos_tienen_suerte(25, 123)`` -> ``16`` |br| + ``cuantos_tienen_suerte(13, 245)`` -> ``74`` |br| + + ~~~~ + def cuantos_tienen_suerte(inicio, fin): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(cuantos_tienen_suerte(1, 1), 0, "Esperado: 0") + self.assertEqual(cuantos_tienen_suerte(1, 7), 1, "Esperado: 1") + self.assertEqual(cuantos_tienen_suerte(1, 20), 3, "Esperado: 3") + self.assertEqual(cuantos_tienen_suerte(25, 123), 16, "Esperado: 16") + self.assertEqual(cuantos_tienen_suerte(1300, 2460), 481, "Esperado: 481") + self.assertEqual(cuantos_tienen_suerte(13, 245), 74, "Esperado: 74") + + + myTests().main() + + + .. tab:: Ejercicio 4_2 + + .. fillintheblank:: q5_9 + + Utilice la función creada en el ejercicio anterior para responder ¿Cuántos números tienen suerte entre 18644 y 33087 (inclusive)? + + - :7995: Tu respuesta es correcta, ¡buen trabajo! + :.*: Tu respuesta es incorrecta, intenta nuevamente. + + +.. tabbed:: quiz5_5 + + .. tab:: Ejercicio 5_1 + + .. activecode:: q5_10 + :nocodelens: + + En el tranquilo pueblo rural de *Ponteironuloville*, todos los teléfonos tienen 6 dígitos. La compañía telefónica establece las siguientes reglas sobre los números: |br| + + 1. No puede haber dos dígitos idénticos consecutivos, porque esto es aburrido + 2. La suma de los dígitos debe ser par, porque esto es legal + 3. El último dígito no puede ser el mismo que el primero, porque eso es mala suerte. + + Entonces, dadas estas reglas perfectamente razonables, bien diseñadas y maduras, desarrolle la función que se llama ``es_numero_ponteironuloville`` que recibe una cadena de enteros positivos y devuelve ``True`` si el número es valido de acuerdo a las reglas de *Ponteironuloville* y ``False`` en caso contrario. + |br| |br| + + Ejemplos: |br| + ``es_numero_ponteironuloville("123457")`` -> ``True`` |br| + ``es_numero_ponteironuloville("234562")`` -> ``False`` |br| + ``es_numero_ponteironuloville("222222")`` -> ``False`` |br| + ``es_numero_ponteironuloville("123456")`` -> ``False`` |br| + ``es_numero_ponteironuloville("312214")`` -> ``False`` |br| + ``es_numero_ponteironuloville("312312")`` -> ``True`` |br| + + ~~~~ + def es_numero_ponteironuloville(numero): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(es_numero_ponteironuloville("123457"), True, "Esperado: True") + self.assertEqual(es_numero_ponteironuloville("234562"), False, "Esperado: False") + self.assertEqual(es_numero_ponteironuloville("304706"), True, "Esperado: True") + self.assertEqual(es_numero_ponteironuloville("222222"), False, "Esperado: False") + self.assertEqual(es_numero_ponteironuloville("123456"), False, "Esperado: False") + self.assertEqual(es_numero_ponteironuloville("312214"), False, "Esperado: False") + self.assertEqual(es_numero_ponteironuloville("312312"), True, "Esperado: True") + self.assertEqual(es_numero_ponteironuloville("131313"), True, "Esperado: True") + self.assertEqual(es_numero_ponteironuloville("249184"), True, "Esperado: True") + self.assertEqual(es_numero_ponteironuloville("012445"), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 5_2 + + .. activecode:: q5_11 + :nocodelens: + :include: q5_10 + + Sabiendo que la función ``split()`` divide una cadena en múltiples cadenas, utilice la función creada en el ejercicio anterior (**OBLIGATORIO** haberla terminado antes y haber pasado todas las pruebas) para terminar la función ``contar_validos`` que devuelve la cantidad de números válidos de la lista de números dada en el siguiente bloque de código. |br| |br| + **Nota**: la lista de números es una cadena, utilice sabiamente la función ``split()`` para obtener un arreglo de cadenas. + ~~~~ + lista_numeros = """236043 237330 239636 240138 242123 246224 249183 252936 + 254711 257200 257607 261424 263814 266794 268649 273050 + 275001 277606 278997 283331 287104 287953 289137 291591 + 292559 292946 295180 295566 297529 300400 304707 306931 + 310638 313595 318449 319021 322082 323796 326266 326880 + 327249 329914 334392 334575 336723 336734 338808 343269 + 346040 350113 353631 357154 361633 361891 364889 365746 + 365749 366426 369156 369444 369689 372896 374983 375223 + 379163 380712 385640 386777 388599 389450 390178 392943 + 394742 395921 398644 398832 401149 402219 405364 408088 + 412901 417683 422267 424767 426613 430474 433910 435054 + 440052 444630 447852 449116 453865 457631 461750 462985 + 463328 466458 469601 473108 476773 477956 481991 482422 + 486195 488359 489209 489388 491928 496569 496964 497901 + 500877 502386 502715 507617 512526 512827 513796 518232 + 521455 524277 528496 529345 531231 531766 535067 535183 + 536593 537360 539055 540582 543708 547492 550779 551595 + 556493 558807 559102 562050 564962 569677 570945 575447 + 579937 580112 580680 582458 583012 585395 586244 587393 + 590483 593112 593894 594293 597525 598184 600455 600953 + 601523 605761 608618 609198 610141 610536 612636 615233 + 618314 622752 626345 626632 628889 629457 629643 633673 + 637656 641136 644176 644973 647617 652218 657143 659902 + 662224 666265 668010 672480 672695 676868 677125 678315""" + + def contar_validos(): + contador = 0 + """ + Escriba su codigo aqui, use la variable creada + """ + return contador + ==== + + + .. tab:: Ejercicio 5_3 + + .. fillintheblank:: q5_12 + + Utilice la función creada en el ejercicio anterior para responder ¿Cuántos números de la lista son válidos de acuerdo a las reglas de *Ponteironuloville*? + + - :39: Tu respuesta es correcta, ¡buen trabajo! + :.*: Tu respuesta es incorrecta, intenta nuevamente. diff --git a/293/_sources/quiz/Quiz5_en.rst.txt b/293/_sources/quiz/Quiz5_en.rst.txt new file mode 100644 index 0000000000..6caff8156d --- /dev/null +++ b/293/_sources/quiz/Quiz5_en.rst.txt @@ -0,0 +1,275 @@ +======== +Quiz - 5 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz5_1 + + .. tab:: Exercise 1_1 + + .. clickablearea:: q5_1_en + :question: The following program declares a variable in the wrong place in the code. Your task is to select the incorrect declaration and select the correct line where it should go. + :iscode: + :feedback: Remember, you cannot use a variable without declaring it previously. + + :click-incorrect:x = 2:endclick: + :click-correct: :endclick: + :click-incorrect:if y > 8 then::endclick: + :click-correct:y = 5:endclick: + :click-incorrect:y = y * 2:endclick: + + :click-incorrect:else::endclick: + :click-incorrect:x = x * 2:endclick: + :click-incorrect:print(x + y)::endclick: + + + .. tab:: Exercise 1_2 + + .. activecode:: q5_2_en + :nocodelens: + + Translate the previous program (with the declaration in the right place) to Python using the following code block. |br| + ~~~~ + + ==== + + + .. tab:: Exercise 1_3 + + .. fillintheblank:: q5_3_en + + What does the previous program print? + + - :9: Your answer is correct, good job! + :.*: Your answer is incorrect, please try again. + + +.. tabbed:: quiz5_2 + + .. tab:: Exercise 2_1 + + .. code-block:: none + + for i = 1 to 9: + if i != 3 then: + for j = 1 to 6: + print("Hello") + + + .. tab:: Exercise 2_2 + + .. activecode:: q5_4_en + :nocodelens: + + Translate the previous program to Python using the following code block. |br| + **Note**: in our pseudolanguage, the loop includes the endpoints, that is, 1 to 4 means 1, 2, 3, 4. |br| + ~~~~ + + ==== + + + .. tab:: Exercise 2_3 + + .. fillintheblank:: q5_5_en + + How many times does the previous program print ``"Hello"``? + + - :48: Your answer is correct, good job! + :.*: Your answer is incorrect, please try again. + + +.. tabbed:: quiz5_3 + + .. tab:: Exercise 3_1 + + .. activecode:: q5_6_en + :nocodelens: + + Develop the function ``pares_divisibles_7`` which receives two positive integers, ``inicio`` and ``fin``, that represent the start and end of a range of numbers. The function must return the amount of numbers that are even and also divisible by 7. |br| |br| + Examples: |br| + ``pares_divisibles_7(1, 7)`` -> ``0`` |br| + ``pares_divisibles_7(25, 123)`` -> ``7`` |br| + ``pares_divisibles_7(13, 245)`` -> ``17`` |br| + + ~~~~ + def pares_divisibles_7(inicio, fin): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(pares_divisibles_7(1, 7), 0, "Expected: 0") + self.assertEqual(pares_divisibles_7(25, 123), 7, "Expected: 7") + self.assertEqual(pares_divisibles_7(13, 245), 17, "Expected: 17") + self.assertEqual(pares_divisibles_7(1300, 2460), 83, "Expected: 83") + self.assertEqual(pares_divisibles_7(1, 2460), 175, "Expected: 175") + + + myTests().main() + + + .. tab:: Exercise 3_2 + + .. fillintheblank:: q5_7_en + + Use the function created in the previous exercise to answer How many numbers are even and also divisible by 7 between 1067 and 3627 (inclusive)? + + - :183: Your answer is correct, good job! + :.*: Your answer is incorrect, try again. + + +.. tabbed:: quiz5_4 + + .. tab:: Exercise 4_1 + + .. activecode:: q5_8_en + :nocodelens: + + Daniela is a very superstitious person. For her, a number is **lucky** if it contains the digit ``2`` but not the ``7``. She is also very curious and wants to know how many **lucky** numbers are in a range of numbers (including the ends)?. That's why she has asked you to make the function called ``cuantos_tienen_suerte`` which receives two positive integers, ``inicio`` and ``fin``, that represent the start and end of a range of numbers. The function must return the amount of numbers that are **lucky**. |br| |br| + Examples: |br| + ``cuantos_tienen_suerte(1, 7)`` -> ``1`` |br| + ``cuantos_tienen_suerte(1, 20)`` -> ``3`` |br| + ``cuantos_tienen_suerte(25, 123)`` -> ``16`` |br| + ``cuantos_tienen_suerte(13, 245)`` -> ``74`` |br| + + ~~~~ + def cuantos_tienen_suerte(inicio, fin): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(cuantos_tienen_suerte(1, 1), 0, "Expected: 0") + self.assertEqual(cuantos_tienen_suerte(1, 7), 1, "Expected: 1") + self.assertEqual(cuantos_tienen_suerte(1, 20), 3, "Expected: 3") + self.assertEqual(cuantos_tienen_suerte(25, 123), 16, "Expected: 16") + self.assertEqual(cuantos_tienen_suerte(1300, 2460), 481, "Expected: 481") + self.assertEqual(cuantos_tienen_suerte(13, 245), 74, "Expected: 74") + + + myTests().main() + + + .. tab:: Exercise 4_2 + + .. fillintheblank:: q5_9_en + + Use the function created in the previous exercise (**MANDATORY** to have finished it before and passed all tests) to answer How many **lucky** numbers are there between 18644 and 33087 (inclusive)? + + - :7995: Your answer is correct, good job! + :.*: Your answer is incorrect, try again. + + +.. tabbed:: quiz5_5 + + .. tab:: Exercise 5_1 + + .. activecode:: q5_10_en + :nocodelens: + + In the quiet rural village of *Ponteironuloville*, all phones have 6 digits. The telephone company establishes the following rules about numbers: | br | + + 1. There cannot be two identical consecutive digits, because this is boring + 2. The sum of the digits must be even, because this is legal + 3. The last digit cannot be the same as the first, because that is bad luck. + + Then, given these perfectly reasonable, well-designed and mature rules, develop the function called ``es_numero_ponteironuloville`` that receives a string of positive integers and returns ``True`` if the number is valid according to the rules of *Ponteironuloville* and ``False`` otherwise. + | br | | br | + + Examples: | br | + ``es_numero_ponteironuloville("123457")`` -> ``True`` | br | + ``es_numero_ponteironuloville("234562")`` -> ``False`` | br | + ``es_numero_ponteironuloville("222222")`` -> ``False`` | br | + ``es_numero_ponteironuloville("123456")`` -> ``False`` | br | + ``es_numero_ponteironuloville("312214")`` -> ``False`` | br | + ``es_numero_ponteironuloville("312312")`` -> ``True`` | br | + + ~~~~ + def es_numero_ponteironuloville(numero): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(es_numero_ponteironuloville("123457"), True, "Expected: True") + self.assertEqual(es_numero_ponteironuloville("234562"), False, "Expected: False") + self.assertEqual(es_numero_ponteironuloville("304706"), True, "Expected: True") + self.assertEqual(es_numero_ponteironuloville("222222"), False, "Expected: False") + self.assertEqual(es_numero_ponteironuloville("123456"), False, "Expected: False") + self.assertEqual(es_numero_ponteironuloville("312214"), False, "Expected: False") + self.assertEqual(es_numero_ponteironuloville("312312"), True, "Expected: True") + self.assertEqual(es_numero_ponteironuloville("131313"), True, "Expected: True") + self.assertEqual(es_numero_ponteironuloville("249184"), True, "Expected: True") + self.assertEqual(es_numero_ponteironuloville("012445"), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 5_2 + + .. activecode:: q5_11_en + :nocodelens: + :include: q5_10_en + + Knowing that the ``split()`` function divides a string into multiple strings, use the function created in the previous exercise (**MANDATORY** to have finished it before and passed all tests) to complete the ``count_valid`` function that returns the number of valid numbers from the list of numbers given in the following block of code. |br| |br| + **Note**: the list of numbers is a string, wisely use the ``split()`` function to obtain a list of strings. + ~~~~ + numbers_list = """236043 237330 239636 240138 242123 246224 249183 252936 + 254711 257200 257607 261424 263814 266794 268649 273050 + 275001 277606 278997 283331 287104 287953 289137 291591 + 292559 292946 295180 295566 297529 300400 304707 306931 + 310638 313595 318449 319021 322082 323796 326266 326880 + 327249 329914 334392 334575 336723 336734 338808 343269 + 346040 350113 353631 357154 361633 361891 364889 365746 + 365749 366426 369156 369444 369689 372896 374983 375223 + 379163 380712 385640 386777 388599 389450 390178 392943 + 394742 395921 398644 398832 401149 402219 405364 408088 + 412901 417683 422267 424767 426613 430474 433910 435054 + 440052 444630 447852 449116 453865 457631 461750 462985 + 463328 466458 469601 473108 476773 477956 481991 482422 + 486195 488359 489209 489388 491928 496569 496964 497901 + 500877 502386 502715 507617 512526 512827 513796 518232 + 521455 524277 528496 529345 531231 531766 535067 535183 + 536593 537360 539055 540582 543708 547492 550779 551595 + 556493 558807 559102 562050 564962 569677 570945 575447 + 579937 580112 580680 582458 583012 585395 586244 587393 + 590483 593112 593894 594293 597525 598184 600455 600953 + 601523 605761 608618 609198 610141 610536 612636 615233 + 618314 622752 626345 626632 628889 629457 629643 633673 + 637656 641136 644176 644973 647617 652218 657143 659902 + 662224 666265 668010 672480 672695 676868 677125 678315""" + + def count_valid(): + count = 0 + """ + Write your code here, using the created variable + """ + return count + ==== + + + .. tab:: Exercise 5_3 + + .. fillintheblank:: q5_12_en + + Use the function created in the previous exercise to answer how many numbers from the list are valid according to the rules of *Ponteironuloville*? + + - :39: Your answer is correct, good job! + :.*: Your answer is incorrect, try again. \ No newline at end of file diff --git a/293/_sources/quiz/Quiz6.rst.txt b/293/_sources/quiz/Quiz6.rst.txt new file mode 100644 index 0000000000..98816abf83 --- /dev/null +++ b/293/_sources/quiz/Quiz6.rst.txt @@ -0,0 +1,339 @@ +========= +Quiz - 6 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz6 + + .. tab:: Ejercicio 1 + + .. activecode:: q6_1 + :nocodelens: + + Desarrolle la función ``dormir`` que toma dos parámetros, + ``dia_semana`` y ``dia_festivo``. Ambos parámetros toman + valores booleanos, es decir pueden ser ``True`` o ``False``. La función actúa + de la siguiente manera: usted puede dormir cuando sea día festivo + o cuando no sea un día entre semana. ``dormir`` devolverá ``True`` + o ``False`` si usted va a dormir o no. |br| |br| + Ejemplos: |br| + ``dormir(False, False)`` -> ``True`` |br| + ``dormir(True, False)`` -> ``False`` |br| + + ~~~~ + def dormir(dia_semana, dia_festivo): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(dormir(False, False), True, "Excelente! obtenido: True esperado: True") + self.assertEqual(dormir(True, False), False, "Excelente! obtenido: False esperado: False") + self.assertEqual(dormir(False, True), True, "Excelente! obtenido: True esperado: True") + self.assertEqual(dormir(True, True), True, "Excelente! obtenido: True esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q6_2 + :nocodelens: + + Desarrolle la función ``alumnos_en_problemas`` que toma dos parámetros, + ``a_sonrie`` y ``b_sonrie``. a y b representan dos estudiantes. + ``a_sonrie`` y ``b_sonrie`` indican si a y b sonríen. Cuando ambos + sonríen o ambos no están sonriendo tenemos problemas. ``alumnos_en_problemas`` + debe devolver ``True`` cuando hay problemas. De lo contrario, devolverá ``False``. + |br| |br| + Ejemplos: |br| + ``alumnos_en_problemas(True, True)`` -> ``True`` |br| + ``alumnos_en_problemas(False, True)`` -> ``False`` |br| + + ~~~~ + def alumnos_en_problemas(a_sonrie, b_sonrie): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(alumnos_en_problemas(True, True), True, "Esperado: True") + self.assertEqual(alumnos_en_problemas(False, False), True, "Esperado: True") + self.assertEqual(alumnos_en_problemas(True, False), False, "Esperado: False") + self.assertEqual(alumnos_en_problemas(False, True), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q6_3 + :nocodelens: + + Desarrolle la función ``suma_doble`` que toma dos parámetros, ``a`` y ``b``. + Ambos son números enteros. La función debe devolver la suma de ``a`` y ``b``. + Sin embargo, si los números son iguales, devuelve el doble de la suma. |br| |br| + Ejemplos: |br| + ``suma_doble(1, 2)`` -> ``3`` |br| + ``suma_doble(2, 2)`` -> ``8`` |br| + + ~~~~ + def suma_doble(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_doble(1, 2), 3, "Excelente! obtenido: 3 esperado: 3") + self.assertEqual(suma_doble(3, 2), 5, "Excelente! obtenido: 5 esperado: 5") + self.assertEqual(suma_doble(2, 2), 8, "Excelente! obtenido: 8 esperado: 8") + self.assertEqual(suma_doble(-1, 0), -1, "Excelente! obtenido: -1 esperado: -1") + self.assertEqual(suma_doble(0, 0), 0, "Excelente! obtenido: 0 esperado: 0") + self.assertEqual(suma_doble(0, 1), 1, "Excelente! obtenido: 1 esperado: 1") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q6_4 + :nocodelens: + + Desarrolle la función ``diferencia_absoluta_21`` que toma un parámetro, ``n``, + y devuelve la diferencia absoluta entre ``n`` y 21 solo si ``n`` es menor + o igual a 21. Si es mayor, entonces devuelve el doble de la diferencia + absoluta entre el número y 21. **Recuerde**: ``abs(x)`` devuelve + el valor absoluto de x. |br| |br| + Ejemplos: |br| + ``diferencia_absoluta_21(19)`` -> ``2`` |br| + ``diferencia_absoluta_21(25)`` -> ``8`` |br| + + ~~~~ + def diferencia_absoluta_21(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(diferencia_absoluta_21(19), 2, "Esperado: 2") + self.assertEqual(diferencia_absoluta_21(10), 11, "Esperado: 11") + self.assertEqual(diferencia_absoluta_21(21), 0, "Esperado: 0") + self.assertEqual(diferencia_absoluta_21(22), 2, "Esperado: 2") + self.assertEqual(diferencia_absoluta_21(25), 8, "Esperado: 8") + self.assertEqual(diferencia_absoluta_21(30), 18, "Esperado: 18") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q6_5 + :nocodelens: + + Desarrolle la función ``problemas_con_loro`` que toma dos parámetros, + ``hablando`` que puede ser ``True`` o ``False``, y ``hora`` que toma un valor + entre 0 y 23. Tenemos un loro, y hay problemas si el loro está hablando + antes de las 7 horas o después de las 20 horas. Devolver ``True`` si hay + problemas o ``False`` si no los hay. |br| |br| + Ejemplos: |br| + ``problemas_con_loro(True, 6)`` -> ``True`` |br| + ``problemas_con_loro(True, 20)`` -> ``False`` |br| + + ~~~~ + def problemas_con_loro(hablando, hora): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(problemas_con_loro(True, 6), True, "Esperado: True") + self.assertEqual(problemas_con_loro(True, 7), False, "Esperado: False") + self.assertEqual(problemas_con_loro(True, 21), True, "Esperado: True") + self.assertEqual(problemas_con_loro(True, 23), True, "Esperado: True") + self.assertEqual(problemas_con_loro(True, 20), False, "Esperado: False") + self.assertEqual(problemas_con_loro(False, 6), False, "Esperado: False") + self.assertEqual(problemas_con_loro(False, 21), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q6_6 + :nocodelens: + + Desarrolle la función ``es_diez`` que toma dos parámetros, ``a`` y ``b``. + Devuelve ``True`` si uno de los parámetros es 10, o si la suma de ambos + es 10. De lo contrario, devuelve ``False``. |br| |br| + Ejemplos: |br| + ``es_diez(9,10)`` -> ``True`` |br| + ``es_diez(1,9)`` -> ``True`` |br| + ``es_diez(8,3)`` -> ``False`` |br| + + ~~~~ + def es_diez(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(es_diez(9, 10), True, "Esperado: True") + self.assertEqual(es_diez(9, 9), False, "Esperado: False") + self.assertEqual(es_diez(1, 9), True, "Esperado: True") + self.assertEqual(es_diez(10, 1), True, "Esperado: True") + self.assertEqual(es_diez(10, 10), True, "Esperado: True") + self.assertEqual(es_diez(8, 2), True, "Esperado: True") + self.assertEqual(es_diez(8, 3), False, "Esperado: False") + self.assertEqual(es_diez(10, 42), True, "Esperado: True") + self.assertEqual(es_diez(12, -2), True, "Esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 7 + + .. activecode:: q6_7 + :nocodelens: + + Desarrolle la función ``distancia_10`` que toma a ``n`` + como parámetro, el cual es un número entero. Devuelve ``True`` si + la diferencia absoluta entre ``n`` y 100 o ``n`` y 200 es menor o + igual que 10. |br| |br| + Ejemplos: |br| + ``distancia_10(93)`` -> ``True`` |br| + ``distancia_10(90)`` -> ``True`` |br| + ``distancia_10(89)`` -> ``False`` |br| + ``distancia_10(210)`` -> ``True`` |br| + ``distancia_10(211)`` -> ``False`` |br| + + ~~~~ + def distancia_10(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(distancia_10(93), True, "Esperado: True") + self.assertEqual(distancia_10(90), True, "Esperado: True") + self.assertEqual(distancia_10(89), False, "Esperado: False") + self.assertEqual(distancia_10(110), True, "Esperado: True") + self.assertEqual(distancia_10(111), False, "Esperado: False") + self.assertEqual(distancia_10(121), False, "Esperado: False") + self.assertEqual(distancia_10(0), False, "Esperado: False") + self.assertEqual(distancia_10(5), False, "Esperado: False") + self.assertEqual(distancia_10(191), True, "Esperado: True") + self.assertEqual(distancia_10(189), False, "Esperado: False") + self.assertEqual(distancia_10(190), True, "Esperado: True") + self.assertEqual(distancia_10(200), True, "Esperado: True") + self.assertEqual(distancia_10(210), True, "Esperado: True") + self.assertEqual(distancia_10(211), False, "Esperado: False") + self.assertEqual(distancia_10(290), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 8 + + .. activecode:: q6_8 + :nocodelens: + + Desarrolle la función ``remover_iesimo`` que recibe una cadena ``s`` no vacía + y un entero positivo ``i``, y devuelva la cadena original sin el i-ésimo carácter. + |br| |br| + Ejemplos: |br| + ``remover_iesimo("Hello", 1)`` -> ``"ello"`` |br| + ``remover_iesimo("Hi", 2)`` -> ``"H"`` |br| + ``remover_iesimo("PyZombiess", 10)`` -> ``"PyZombies"`` |br| + + ~~~~ + def remover_iesimo(s, i): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(quitar_caracter("Hi", 0), "i", "Esperado: i") + self.assertEqual(quitar_caracter("Hi", 1), "H", "Esperado: H") + self.assertEqual(quitar_caracter("code", 0), "ode", "Esperado: ode") + self.assertEqual(quitar_caracter("code", 1), "cde", "Esperado: cde") + self.assertEqual(quitar_caracter("code", 2), "coe", "Esperado: coe") + self.assertEqual(quitar_caracter("code", 3), "cod", "Esperado: cod") + self.assertEqual(quitar_caracter("gatito", 1), "gtito", "Esperado: gtito") + self.assertEqual(quitar_caracter("gatito", 0), "atito", "Esperado: atito") + self.assertEqual(quitar_caracter("gatito", 4), "gatio", "Esperado: gatio") + self.assertEqual(quitar_caracter("chocolate", 8), "chocolat", "Esperado: chocolat") + + + myTests().main() + + + .. tab:: Ejercicio 9 + + .. activecode:: q6_9 + :nocodelens: + + Desarrolle la función ``intercambiar`` que toma a ``s`` como parámetro, + representando una cadena. Si ``s`` tiene un tamaño menor o igual a 1, se + devuelve la misma cadena. De lo contrario, la primera y última letra de ``s`` + se intercambian. |br| |br| + Ejemplos: |br| + ``intercambiar("codigo")`` -> ``"oodigc"`` |br| + ``intercambiar("a")`` -> ``"a"`` |br| + ``intercambiar("ab")`` -> ``"ba"`` |br| + + ~~~~ + def intercambiar(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(intercambiar("code"), "eodc", "Esperado: eodc") + self.assertEqual(intercambiar("a"), "a", "Esperado: a") + self.assertEqual(intercambiar("ab"), "ba", "Esperado: ba") + self.assertEqual(intercambiar("abc"), "cba", "Esperado: cba") + self.assertEqual(intercambiar(" "), " ", "Esperado: ' '") + self.assertEqual(intercambiar("nythoP"), "Python", "Esperado: Python") + self.assertEqual(intercambiar("hello"), "oellh", "Esperado: oellh") + self.assertEqual(intercambiar("Chocolate"), "ehocolatC", "Esperado: ehocolatC") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz6_en.rst.txt b/293/_sources/quiz/Quiz6_en.rst.txt new file mode 100644 index 0000000000..e77df54284 --- /dev/null +++ b/293/_sources/quiz/Quiz6_en.rst.txt @@ -0,0 +1,331 @@ +========= +Quiz - 6 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz6 + + .. tab:: Exercise 1 + + .. activecode:: q6_1_en + :nocodelens: + + Develop the function ``sleep`` that takes two parameters, + ``weekday`` and ``holiday``, both parameters take boolean values, + meaning they can be either ``True`` or ``False``. The function acts as follows: + you can sleep when it's a holiday or when it's not a weekday. + ``sleep`` will return ``True`` or ``False`` whether or not you will sleep. |br| |br| + Examples: |br| + ``sleep(False, False)`` -> ``True`` |br| + ``sleep(True, False)`` -> ``False`` |br| + + ~~~~ + def sleep(weekday, holiday): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(sleep(False, False), True, "Excellent! Obtained: True Expected: True") + self.assertEqual(sleep(True, False), False, "Excellent! Obtained: False Expected: False") + self.assertEqual(sleep(False, True), True, "Excellent! Obtained: True Expected: True") + self.assertEqual(sleep(True, True), True, "Excellent! Obtained: True Expected: True") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q6_2_en + :nocodelens: + + Develop the function ``students_in_trouble`` that takes two parameters, + ``a_smiling`` and ``b_smiling``. a and b represent two students. + ``a_smiling`` and ``b_smiling`` indicate if a and b are smiling. When both + are smiling or both are not smiling we have trouble. ``students_in_trouble`` + should return ``True`` when there is trouble. Otherwise, it will return ``False``. + |br| |br| + Examples: |br| + ``students_in_trouble(True, True)`` -> ``True`` |br| + ``students_in_trouble(False, True)`` -> ``False`` |br| + + ~~~~ + def students_in_trouble(a_smiling, b_smiling): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(students_in_trouble(True, True), True, "Expected: True") + self.assertEqual(students_in_trouble(False, False), True, "Expected: True") + self.assertEqual(students_in_trouble(True, False), False, "Expected: False") + self.assertEqual(students_in_trouble(False, True), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q6_3_en + :nocodelens: + + Develop the function ``double_sum`` that takes two parameters, ``a`` and ``b``. + Both are integers. The function should return the sum of ``a`` and ``b``. + However, if the numbers are equal, it returns twice the sum. |br| |br| + Examples: |br| + ``double_sum(1, 2)`` -> ``3`` |br| + ``double_sum(2, 2)`` -> ``8`` |br| + + ~~~~ + def double_sum(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(double_sum(1, 2), 3, "Excellent! gotten: 3 expected: 3") + self.assertEqual(double_sum(3, 2), 5, "Excellent! gotten: 5 expected: 5") + self.assertEqual(double_sum(2, 2), 8, "Excellent! gotten: 8 expected: 8") + self.assertEqual(double_sum(-1, 0), -1, "Excellent! gotten: -1 expected: -1") + self.assertEqual(double_sum(0, 0), 0, "Excellent! gotten: 0 expected: 0") + self.assertEqual(double_sum(0, 1), 1, "Excellent! gotten: 1 expected: 1") + + + myTests().main() + + .. tab:: Exercise 4 + + .. activecode:: q6_4_en + :nocodelens: + + Develop the function ``absolute_difference_21`` that takes a parameter, ``n``, + and returns the absolute difference between ``n`` and 21 only if ``n`` + is less than or equal to 21. If it is greater, then it returns twice the + absolute difference between the number and 21. **Remember**: ``abs(x)`` returns + the absolute value of x. |br| |br| + Examples: |br| + ``absolute_difference_21(19)`` -> ``2`` |br| + ``absolute_difference_21(25)`` -> ``8`` |br| + + ~~~~ + def absolute_difference_21(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(absolute_difference_21(19), 2, "Expected: 2") + self.assertEqual(absolute_difference_21(10), 11, "Expected: 11") + self.assertEqual(absolute_difference_21(21), 0, "Expected: 0") + self.assertEqual(absolute_difference_21(22), 2, "Expected: 2") + self.assertEqual(absolute_difference_21(25), 8, "Expected: 8") + self.assertEqual(absolute_difference_21(30), 18, "Expected: 18") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q6_5_en + :nocodelens: + + Develop the function ``parrot_trouble`` that takes two parameters, + ``talking``, which can be ``True`` or ``False``, and ``hour``, which takes a value + between 0 and 23. We have a parrot, and there is trouble if the parrot is talking + before 7 hours or after 20 hours. Return ``True`` if there are + problems or ``False`` if there are not. |br| |br| + Examples: |br| + ``parrot_trouble(True, 6)`` -> ``True`` |br| + ``parrot_trouble(True, 20)`` -> ``False`` |br| + + ~~~~ + def parrot_trouble(talking, hour): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(parrot_trouble(True, 6), True, "Expected: True") + self.assertEqual(parrot_trouble(True, 7), False, "Expected: False") + self.assertEqual(parrot_trouble(True, 21), True, "Expected: True") + self.assertEqual(parrot_trouble(True, 23), True, "Expected: True") + self.assertEqual(parrot_trouble(True, 20), False, "Expected: False") + self.assertEqual(parrot_trouble(False, 6), False, "Expected: False") + self.assertEqual(parrot_trouble(False, 21), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 6 + + .. activecode:: q6_6_en + :nocodelens: + + Develop the function ``makes10`` that takes two parameters, ``a`` and ``b``. + Returns ``True`` if one of the parameters is 10, or if the sum of both + is 10. Otherwise, it returns ``False``. |br| |br| + Examples: |br| + ``makes10(9,10)`` -> ``True`` |br| + ``makes10(1,9)`` -> ``True`` |br| + ``makes10(8,3)`` -> ``False`` |br| + + ~~~~ + def makes10(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(makes10(9, 10), True, "Expected: True") + self.assertEqual(makes10(9, 9), False, "Expected: False") + self.assertEqual(makes10(1, 9), True, "Expected: True") + self.assertEqual(makes10(10, 1), True, "Expected: True") + self.assertEqual(makes10(10, 10), True, "Expected: True") + self.assertEqual(makes10(8, 2), True, "Expected: True") + self.assertEqual(makes10(8, 3), False, "Expected: False") + self.assertEqual(makes10(10, 42), True, "Expected: True") + self.assertEqual(makes10(12, -2), True, "Expected: True") + + + myTests().main() + + + .. tab:: Exercise 7 + + .. activecode:: q6_7_en + :nocodelens: + + Develop the function ``near_hundred`` that takes ``n`` + as a parameter, which is an integer. Returns ``True`` if + the absolute difference between ``n`` and 100 or ``n`` and 200 is less than or + equal to 10. |br| |br| + Examples: |br| + ``near_hundred(93)`` -> ``True`` |br| + ``near_hundred(90)`` -> ``True`` |br| + ``near_hundred(89)`` -> ``False`` |br| + ``near_hundred(210)`` -> ``True`` |br| + ``near_hundred(211)`` -> ``False`` |br| + + ~~~~ + def near_hundred(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(near_hundred(93), True, "Expected: True") + self.assertEqual(near_hundred(90), True, "Expected: True") + self.assertEqual(near_hundred(89), False, "Expected: False") + self.assertEqual(near_hundred(110), True, "Expected: True") + self.assertEqual(near_hundred(111), False, "Expected: False") + self.assertEqual(near_hundred(121), False, "Expected: False") + self.assertEqual(near_hundred(0), False, "Expected: False") + self.assertEqual(near_hundred(5), False, "Expected: False") + self.assertEqual(near_hundred(191), True, "Expected: True") + self.assertEqual(near_hundred(189), False, "Expected: False") + self.assertEqual(near_hundred(190), True, "Expected: True") + self.assertEqual(near_hundred(200), True, "Expected: True") + self.assertEqual(near_hundred(210), True, "Expected: True") + self.assertEqual(near_hundred(211), False, "Expected: False") + self.assertEqual(near_hundred(290), False, "Expected: False") + + + myTests().main() + + .. tab:: Exercise 8 + + .. activecode:: q6_8_en + :nocodelens: + + Develop the function ``remover_iesimo`` that receives a non-empty string ``s`` and a positive integer ``i``, and returns the original string without the i-th character. |br| |br| + Examples: |br| + ``remover_iesimo("Hello", 1)`` -> ``"ello"`` |br| + ``remover_iesimo("Hi", 2)`` -> ``"H"`` |br| + ``remover_iesimo("PyZombiess", 10)`` -> ``"PyZombies"`` |br| + + ~~~~ + def remover_iesimo(s, i): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(quitar_caracter("Hi", 0), "i", "Expected: i") + self.assertEqual(quitar_caracter("Hi", 1), "H", "Expected: H") + self.assertEqual(quitar_caracter("code", 0), "ode", "Expected: ode") + self.assertEqual(quitar_caracter("code", 1), "cde", "Expected: cde") + self.assertEqual(quitar_caracter("code", 2), "coe", "Expected: coe") + self.assertEqual(quitar_caracter("code", 3), "cod", "Expected: cod") + self.assertEqual(quitar_caracter("gatito", 1), "gtito", "Expected: gtito") + self.assertEqual(quitar_caracter("gatito", 0), "atito", "Expected: atito") + self.assertEqual(quitar_caracter("gatito", 4), "gatio", "Expected: gatio") + self.assertEqual(quitar_caracter("chocolate", 8), "chocolat", "Expected: chocolat") + + + myTests().main() + + + .. tab:: Exercise 9 + + .. activecode:: q6_9_en + :nocodelens: + + Develop the function ``intercambiar`` that takes ``s`` as a parameter, representing a string. If ``s`` has a length of 1 or less, the same string is returned. Otherwise, the first and last letter of ``s`` are exchanged. |br| |br| + Examples: |br| + ``intercambiar("codigo")`` -> ``"oodigc"`` |br| + ``intercambiar("a")`` -> ``"a"`` |br| + ``intercambiar("ab")`` -> ``"ba"`` |br| + + ~~~~ + def intercambiar(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(intercambiar("code"), "eodc", "Expected: eodc") + self.assertEqual(intercambiar("a"), "a", "Expected: a") + self.assertEqual(intercambiar("ab"), "ba", "Expected: ba") + self.assertEqual(intercambiar("abc"), "cba", "Expected: cba") + self.assertEqual(intercambiar(" "), " ", "Expected: ' '") + self.assertEqual(intercambiar("nythoP"), "Python", "Expected: Python") + self.assertEqual(intercambiar("hello"), "oellh", "Expected: oellh") + self.assertEqual(intercambiar("Chocolate"), "ehocolatC", "Expected: ehocolatC") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz7.rst.txt b/293/_sources/quiz/Quiz7.rst.txt new file mode 100644 index 0000000000..f026e4b46b --- /dev/null +++ b/293/_sources/quiz/Quiz7.rst.txt @@ -0,0 +1,424 @@ +========= +Quiz - 7 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz7 + + .. tab:: Ejercicio 1 + + .. activecode:: q7_1 + :nocodelens: + + Desarrolle la función ``multi_cadena`` que recibe como parámetros una cadena ``s`` y un entero positivo ``n`` y devuelve una nueva cadena que contiene ``n`` copias de la cadena original |br| |br| + Ejemplos:|br| + ``multi_cadena("Hola", 2)`` -> ``"HolaHola"`` |br| + ``multi_cadena("Hola", 5)`` -> ``"HolaHolaHolaHolaHola"`` + + ~~~~ + def multi_cadena(s, n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(multi_cadena("Hola", 2), "HolaHola", "Esperado: HolaHola") + self.assertEqual( + multi_cadena("Hola", 3), "HolaHolaHola", "Esperado: HolaHolaHola" + ) + self.assertEqual(multi_cadena("Hi", 1), "Hi", "Esperado: Hi") + self.assertEqual(multi_cadena("Hi", 0), "", "Esperado: ''") + self.assertEqual(multi_cadena("Hi", 5), "HiHiHiHiHi", "Esperado: HiHiHiHiHi") + self.assertEqual( + multi_cadena("Oh Boy!", 2), "Oh Boy!Oh Boy!", "Esperado: Oh Boy!Oh Boy!" + ) + self.assertEqual(multi_cadena("x", 4), "xxxx", "Esperado: xxxx") + self.assertEqual(multi_cadena("", 4), "", "Esperado: ''") + self.assertEqual(multi_cadena("code", 2), "codecode", "Esperado: codecode") + self.assertEqual( + multi_cadena("code", 3), "codecodecode", "Esperado: codecodecode" + ) + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q7_2 + :nocodelens: + + Desarrolle la función ``expandir_cadena`` que recibe una cadena ``s`` y devuelva una nueva cadena siguiendo el patrón descrito en los ejemplos |br| |br| + Ejemplos:|br| + ``expandir_cadena("Code")`` -> ``"CCoCodCode"`` |br| + ``expandir_cadena("abc")`` -> ``"aababc"`` |br| + ``expandir_cadena("ab")`` -> ``"aab"`` |br| + + ~~~~ + def expandir_cadena(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(expandir_cadena("Code"), "CCoCodCode", "Esperado: CCoCodCode") + self.assertEqual(expandir_cadena("abc"), "aababc", "Esperado: aababc") + self.assertEqual(expandir_cadena("ab"), "aab", "Esperado: aab") + self.assertEqual(expandir_cadena("x"), "x", "Esperado: x") + self.assertEqual(expandir_cadena("fade"), "ffafadfade", "Esperado: ffafadfade") + self.assertEqual( + expandir_cadena("There"), "TThTheTherThere", "Esperado: TThTheTherThere" + ) + self.assertEqual( + expandir_cadena("Kitten"), + "KKiKitKittKitteKitten", + "Esperado: KKiKitKittKitteKitten", + ) + self.assertEqual(expandir_cadena("Bye"), "BByBye", "Esperado: BByBye") + self.assertEqual(expandir_cadena("Good"), "GGoGooGood", "Esperado: GGoGooGood") + self.assertEqual(expandir_cadena("Bad"), "BBaBad", "Esperado: BBaBad") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q7_3 + :nocodelens: + + + Desarrolle la función ``contar_apariciones_9`` que recibe como parámetro una lista no vacía de números enteros ``numeros`` y devuelva cuántas veces aparece el número 9 en la lista |br| |br| + Ejemplo: ``contar_apariciones_9([1, 99, 9])`` -> ``1`` + + ~~~~ + def contar_apariciones_9(numeros): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(contar_apariciones_9([1, 99, 9]), 1, "Esperado: 1") + self.assertEqual(contar_apariciones_9([1, 9, 9]), 2, "Esperado: 2") + self.assertEqual(contar_apariciones_9([1, 9, 9, 3, 9]), 3, "Esperado: 3") + self.assertEqual(contar_apariciones_9([1, 2, 3]), 0, "Esperado: 0") + self.assertEqual(contar_apariciones_9([1]), 0, "Esperado: 1") + self.assertEqual(contar_apariciones_9([4, 2, 4, 3, 1]), 0, "Esperado: 0") + self.assertEqual(contar_apariciones_9([9, 2, 99, 3, 1]), 1, "Esperado: 1") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q7_4 + :nocodelens: + + + Desarrolle la función ``verificar_comienzo_9`` que recibe una lista de números enteros ``numeros`` y verifica si al menos uno de los primeros cuatro números es un 9 |br| |br| + Ejemplos:|br| + ``verificar_comienzo_9([1, 2, 9, 3, 4])`` -> ``True`` |br| + ``verificar_comienzo_9([1, 2, 3, 4, 9])`` -> ``False`` |br| + ``verificar_comienzo_9([1, 2, 3, 4, 5])`` -> ``False`` |br| + ``verificar_comienzo_9([1, 2, 9])`` -> ``True`` |br| + + ~~~~ + def verificar_comienzo_9(numeros): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(verificar_comienzo_9([1, 2, 9, 3, 4]), True, "Esperado: True") + self.assertEqual(verificar_comienzo_9([1, 2, 3, 4, 9]), False, "Esperado: False") + self.assertEqual(verificar_comienzo_9([1, 2, 3, 4, 5]), False, "Esperado: False") + self.assertEqual(verificar_comienzo_9([9, 2, 3]), True, "Esperado: True") + self.assertEqual(verificar_comienzo_9([1, 9, 9]), True, "Esperado: True") + self.assertEqual(verificar_comienzo_9([1, 2, 3]), False, "Esperado: False") + self.assertEqual(verificar_comienzo_9([1, 9]), True, "Esperado: True") + self.assertEqual(verificar_comienzo_9([5, 5]), False, "Esperado: False") + self.assertEqual(verificar_comienzo_9([2]), False, "Esperado: False") + self.assertEqual(verificar_comienzo_9([9]), True, "Esperado: True") + self.assertEqual(verificar_comienzo_9([]), False, "Esperado: False") + self.assertEqual(verificar_comienzo_9([3, 9, 2, 3, 3]), True, "Esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q7_5 + :nocodelens: + + + Desarrolle la función ``hola_usuario`` que recibe como parámetro una cadena ``nombre`` que representa el nombre de un usuario y devuelva un saludo con este nombre |br| |br| + Ejemplos: |br| + ``hola_usuario("Bob")`` -> ``"¡Hola Bob!"`` |br| + ``hola_usuario("Alice")`` -> ``"¡Hola Alice!"`` |br| + ``hola_usuario("X")`` -> ``"¡Hola X!"`` |br| + + ~~~~ + def hola_usuario(nombre): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(hola_usuario("Bob"), "¡Hola Bob!", "Esperado: ¡Hola Bob!") + self.assertEqual(hola_usuario("Alice"), "¡Hola Alice!", "Esperado: ¡Hola Alice!") + self.assertEqual(hola_usuario("X"), "¡Hola X!", "Esperado: ¡Hola X!") + self.assertEqual(hola_usuario("Hola"), "¡Hola Hola!", "Esperado: ¡Hola Hola!") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q7_6 + :nocodelens: + + + Desarrolle la función ``crear_etiquetas`` que recibe dos cadenas ``etiqueta`` y ``palabra`` y devuelva una nueva cadena formateada siguiendo el patrón de los ejemplos |br| |br| + Ejemplos: |br| + ``crear_etiquetas("i", "Yay")`` -> ``"Yay"`` |br| + ``crear_etiquetas("i", "Hello")`` -> ``"Hello"`` |br| + ``crear_etiquetas("cite", "Yay")`` -> ``"Yay"`` |br| + + ~~~~ + def crear_etiquetas(etiqueta, palabra): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(crear_etiquetas("i", "Yay"), "Yay", "Esperado: Yay") + self.assertEqual(crear_etiquetas("i", "Hello"), "Hello", "Esperado:Hello") + self.assertEqual( + crear_etiquetas("cite", "Yay"), + "Yay", + "Esperado: Yay", + ) + self.assertEqual( + crear_etiquetas("address", "here"), + "
here
", + "Esperado:
here
", + ) + self.assertEqual( + crear_etiquetas("body", "Heart"), + "Heart", + "Esperado: Heart", + ) + self.assertEqual(crear_etiquetas("i", "i"), "i", "Esperado: i") + self.assertEqual(crear_etiquetas("i", ""), "", "Esperado: ") + + + myTests().main() + + + .. tab:: Ejercicio 7 + + .. activecode:: q7_7 + :nocodelens: + + + Desarrolle la función ``repetir_letras`` que recibe una cadena ``s`` de al menos dos caracteres y devuelve una nueva cadena con las dos últimas letras repetidas tres veces |br| |br| + Ejemplos: |br| + ``repetir_letras("Hello")`` -> ``"lololo"`` |br| + ``repetir_letras("abb")`` -> ``"bbbbbb"`` |br| + ``repetir_letras("Hi")`` -> ``"HiHiHi"`` |br| + + ~~~~ + def repetir_letras(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(repetir_letras("Hello"), "lololo", "Esperado: lololo") + self.assertEqual(repetir_letras("ab"), "ababab", "Esperado: ababab") + self.assertEqual(repetir_letras("Hi"), "HiHiHi", "Esperado: HiHiHi") + self.assertEqual(repetir_letras("Candy"), "dydydy", "Esperado: dydydy") + self.assertEqual(repetir_letras("Code"), "dedede", "Esperado: dedede") + + + myTests().main() + + + .. tab:: Ejercicio 8 + + .. activecode:: q7_8 + :nocodelens: + + + Desarrolle la función ``otra_repetir_letras`` (variante de la función del Ejercicio 8) que recibe una cadena ``s`` de al menos dos caracteres y un entero positivo ``n`` y devuelva una nueva cadena con las dos últimas letras repetidas ``n`` veces |br| |br| + Ejemplos: |br| + ``otra_repetir_letras("Hello", 3)`` -> ``"lololo"`` |br| + ``otra_repetir_letras("abb", 1)`` -> ``"bb"`` |br| + ``otra_repetir_letras("Hi", 5)`` -> ``"HiHiHiHiHi"`` |br| + + ~~~~ + def otra_repetir_letras(s, n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(otra_repetir_letras("Hello", 3), "lololo", "Esperado: lololo") + self.assertEqual(otra_repetir_letras("ab", 2), "abab", "Esperado: abab") + self.assertEqual(otra_repetir_letras("Hi", 6), "HiHiHiHiHiHi", "Esperado: HiHiHi") + self.assertEqual(otra_repetir_letras("Candy", 1), "dy", "Esperado: dy") + self.assertEqual(otra_repetir_letras("Code", 0), "", "Esperado: ''") + + + myTests().main() + + + .. tab:: Ejercicio 9 + + .. activecode:: q7_9 + :nocodelens: + + + Desarrolle la función ``primera_mitad`` que recibe una cadena ``s`` y devuelve la primera mitad de la cadena original |br| |br| + Ejemplos:|br| + ``primera_mitad("WooHoo")`` -> ``"Woo"`` |br| + ``primera_mitad("HelloThere")`` -> ``"Hello"`` |br| + ``primera_mitad("abcdef")`` -> ``"abc"`` |br| + + ~~~~ + def primera_mitad(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(primera_mitad("WooHoo"), "Woo", "Esperado: Woo") + self.assertEqual(primera_mitad("HelloThere"), "Hello", "Esperado: Hello") + self.assertEqual(primera_mitad("abcdef"), "abc", "Esperado: abc") + self.assertEqual(primera_mitad(""), "", "Esperado: ") + self.assertEqual(primera_mitad("ab"), "a", "Esperado: a") + self.assertEqual(primera_mitad("0123456789"), "01234", "Esperado: 01234") + self.assertEqual(primera_mitad("kitten"), "kit", "Esperado: kit") + + + myTests().main() + + + .. tab:: Ejercicio 10 + + .. activecode:: q7_10 + :nocodelens: + + + Desarrolle la función ``remover_primer_ultimo`` que recibe una cadena ``s`` de al menos dos caracteres y devuelva una cadena sin el primer ni el último carácter |br| |br| + Ejemplos: |br| + ``remover_primer_ultimo("Hello")`` -> ``"ell"`` |br| + ``remover_primer_ultimo("python")`` -> ``"ytho"`` |br| + ``remover_primer_ultimo("coding")`` -> ``"odin"`` |br| + + ~~~~ + def remover_primer_ultimo(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(remover_primer_ultimo("Hello"), "ell", "Esperado: ell") + self.assertEqual(remover_primer_ultimo("Python"), "ytho", "Esperado: ytho") + self.assertEqual(remover_primer_ultimo("coding"), "odin", "Esperado: odin") + self.assertEqual(remover_primer_ultimo("code"), "od", "Esperado: od") + self.assertEqual(remover_primer_ultimo("ab"), "", "Esperado: ") + self.assertEqual(remover_primer_ultimo(" PyZombies "), "PyZombies", "Esperado: PyZombies") + self.assertEqual(remover_primer_ultimo("Chocolate!"), "hocolate", "Esperado: hocolate") + self.assertEqual(remover_primer_ultimo("kitten"), "itte", "Esperado: itte") + self.assertEqual(remover_primer_ultimo("woohoo"), "ooho", "Esperado: ooho") + + + myTests().main() + + + .. tab:: Ejercicio 11 + + .. activecode:: q7_11 + :nocodelens: + + + Desarrolle la función ``rotar_izq_2`` que recibe una cadena ``s`` de al menos dos caracteres y devuelva la cadena original rotada 2 posiciones a la izquierda |br| |br| + Ejemplos:|br| + ``rotar_izq_2("Hello")`` -> ``"lloHe"`` |br| + ``rotar_izq_2("Hi")`` -> ``"Hi"`` |br| + + ~~~~ + def rotar_izq_2(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(rotar_izq_2("Hello"), "lloHe", "Esperado: lloHe") + self.assertEqual(rotar_izq_2("python"), "thonpy", "Esperado: thonpy") + self.assertEqual(rotar_izq_2("Hi"), "Hi", "Esperado: Hi") + self.assertEqual(rotar_izq_2("code"), "deco", "Esperado: deco") + self.assertEqual(rotar_izq_2("cat"), "tca", "Esperado: tca") + self.assertEqual(rotar_izq_2("12345"), "34512", "Esperado: 34512") + self.assertEqual( + rotar_izq_2("Chocolate"), "ocolateCh", "Esperado: ocolateCh" + ) + self.assertEqual(rotar_izq_2("bricks"), "icksbr", "Esperado: icksbr") + self.assertEqual( + rotar_izq_2("isPyzomb"), "PyZombies", "Esperado: PyZombies" + ) + + + myTests().main() diff --git a/293/_sources/quiz/Quiz7_en.rst.txt b/293/_sources/quiz/Quiz7_en.rst.txt new file mode 100644 index 0000000000..5b2bb9268d --- /dev/null +++ b/293/_sources/quiz/Quiz7_en.rst.txt @@ -0,0 +1,431 @@ +========= +Quiz - 7 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz7 + + .. tab:: Exercise 1 + + .. activecode:: q7_1_en + :nocodelens: + + Develop the function ``multi_cadena`` that receives as parameters a string ``s`` and a positive integer ``n`` and returns a new string that contains ``n`` copies of the original string |br| |br| + Examples:|br| + ``multi_cadena("Hola", 2)`` -> ``"HolaHola"`` |br| + ``multi_cadena("Hola", 5)`` -> ``"HolaHolaHolaHolaHola"`` + + ~~~~ + def multi_cadena(s, n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(multi_cadena("Hola", 2), "HolaHola", "Expected: HolaHola") + self.assertEqual( + multi_cadena("Hola", 3), "HolaHolaHola", "Expected: HolaHolaHola" + ) + self.assertEqual(multi_cadena("Hi", 1), "Hi", "Expected: Hi") + self.assertEqual(multi_cadena("Hi", 0), "", "Expected: ''") + self.assertEqual(multi_cadena("Hi", 5), "HiHiHiHiHi", "Expected: HiHiHiHiHi") + self.assertEqual( + multi_cadena("Oh Boy!", 2), "Oh Boy!Oh Boy!", "Expected: Oh Boy!Oh Boy!" + ) + self.assertEqual(multi_cadena("x", 4), "xxxx", "Expected: xxxx") + self.assertEqual(multi_cadena("", 4), "", "Expected: ''") + self.assertEqual(multi_cadena("code", 2), "codecode", "Expected: codecode") + self.assertEqual( + multi_cadena("code", 3), "codecodecode", "Expected: codecodecode" + ) + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q7_2_en + :nocodelens: + + Develop the function ``expandir_cadena`` that receives a string ``s`` and returns a new string following the pattern described in the examples |br| |br| + Examples:|br| + ``expandir_cadena("Code")`` -> ``"CCoCodCode"`` |br| + ``expandir_cadena("abc")`` -> ``"aababc"`` |br| + ``expandir_cadena("ab")`` -> ``"aab"`` |br| + + ~~~~ + def expandir_cadena(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(expandir_cadena("Code"), "CCoCodCode", "Expected: CCoCodCode") + self.assertEqual(expandir_cadena("abc"), "aababc", "Expected: aababc") + self.assertEqual(expandir_cadena("ab"), "aab", "Expected: aab") + self.assertEqual(expandir_cadena("x"), "x", "Expected: x") + self.assertEqual(expandir_cadena("fade"), "ffafadfade", "Expected: ffafadfade") + self.assertEqual( + expandir_cadena("There"), "TThTheTherThere", "Expected: TThTheTherThere" + ) + self.assertEqual( + expandir_cadena("Kitten"), + "KKiKitKittKitteKitten", + "Expected: KKiKitKittKitteKitten", + ) + self.assertEqual(expandir_cadena("Bye"), "BByBye", "Expected: BByBye") + self.assertEqual(expandir_cadena("Good"), "GGoGooGood", "Expected: GGoGooGood") + self.assertEqual(expandir_cadena("Bad"), "BBaBad", "Expected: BBaBad") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q7_3_en + :nocodelens: + + + Develop the function ``contar_apariciones_9`` that receives as parameter a non-empty list of integers ``numeros`` and returns how many times the number 9 appears in the list |br| |br| + Example: ``contar_apariciones_9([1, 99, 9])`` -> ``1`` + + ~~~~ + def contar_apariciones_9(numeros): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(contar_apariciones_9([1, 99, 9]), 1, "Expected: 1") + self.assertEqual(contar_apariciones_9([1, 9, 9]), 2, "Expected: 2") + self.assertEqual(contar_apariciones_9([1, 9, 9, 3, 9]), 3, "Expected: 3") + self.assertEqual(contar_apariciones_9([1, 2, 3]), 0, "Expected: 0") + self.assertEqual(contar_apariciones_9([1]), 0, "Expected: 1") + self.assertEqual(contar_apariciones_9([4, 2, 4, 3, 1]), 0, "Expected: 0") + self.assertEqual(contar_apariciones_9([9, 2, 99, 3, 1]), 1, "Expected: 1") + + + myTests().main() + + .. tab:: Exercise 4 + + .. activecode:: q7_4_en + :nocodelens: + + + Develop the function ``verificar_comienzo_9`` that receives a list of integer numbers ``numeros`` and verifies if at least one of the first four numbers is a 9 |br| |br| + Examples:|br| + ``verificar_comienzo_9([1, 2, 9, 3, 4])`` -> ``True`` |br| + ``verificar_comienzo_9([1, 2, 3, 4, 9])`` -> ``False`` |br| + ``verificar_comienzo_9([1, 2, 3, 4, 5])`` -> ``False`` |br| + ``verificar_comienzo_9([1, 2, 9])`` -> ``True`` |br| + + ~~~~ + def verificar_comienzo_9(numeros): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(verificar_comienzo_9([1, 2, 9, 3, 4]), True, "Expected: True") + self.assertEqual(verificar_comienzo_9([1, 2, 3, 4, 9]), False, "Expected: False") + self.assertEqual(verificar_comienzo_9([1, 2, 3, 4, 5]), False, "Expected: False") + self.assertEqual(verificar_comienzo_9([9, 2, 3]), True, "Expected: True") + self.assertEqual(verificar_comienzo_9([1, 9, 9]), True, "Expected: True") + self.assertEqual(verificar_comienzo_9([1, 2, 3]), False, "Expected: False") + self.assertEqual(verificar_comienzo_9([1, 9]), True, "Expected: True") + self.assertEqual(verificar_comienzo_9([5, 5]), False, "Expected: False") + self.assertEqual(verificar_comienzo_9([2]), False, "Expected: False") + self.assertEqual(verificar_comienzo_9([9]), True, "Expected: True") + self.assertEqual(verificar_comienzo_9([]), False, "Expected: False") + self.assertEqual(verificar_comienzo_9([3, 9, 2, 3, 3]), True, "Expected: True") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q7_5_en + :nocodelens: + + + Develop the function ``hola_usuario`` that receives as a parameter a string ``nombre`` that represents a user's name and returns a greeting using this name |br| |br| + Examples: |br| + ``hola_usuario("Bob")`` -> ``"¡Hola Bob!"`` |br| + ``hola_usuario("Alice")`` -> ``"¡Hola Alice!"`` |br| + ``hola_usuario("X")`` -> ``"¡Hola X!"`` |br| + + ~~~~ + def hola_usuario(nombre): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(hola_usuario("Bob"), "¡Hola Bob!", "Expected: ¡Hola Bob!") + self.assertEqual(hola_usuario("Alice"), "¡Hola Alice!", "Expected: ¡Hola Alice!") + self.assertEqual(hola_usuario("X"), "¡Hola X!", "Expected: ¡Hola X!") + self.assertEqual(hola_usuario("Hola"), "¡Hola Hola!", "Expected: ¡Hola Hola!") + + + myTests().main() + + .. tab:: Exercise 6 + + .. activecode:: q7_6_en + :nocodelens: + + Develop the function ``crear_etiquetas`` that receives two strings ``etiqueta`` and ``palabra`` and returns a new formatted string following the pattern of the examples |br| |br| + Examples: |br| + ``crear_etiquetas("i", "Yay")`` -> ``"Yay"`` |br| + ``crear_etiquetas("i", "Hello")`` -> ``"Hello"`` |br| + ``crear_etiquetas("cite", "Yay")`` -> ``"Yay"`` |br| + + ~~~~ + def crear_etiquetas(etiqueta, palabra): + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(crear_etiquetas("i", "Yay"), "Yay", "Expected: Yay") + self.assertEqual(crear_etiquetas("i", "Hello"), "Hello", "Expected:Hello") + self.assertEqual( + crear_etiquetas("cite", "Yay"), + "Yay", + "Expected: Yay", + ) + self.assertEqual( + crear_etiquetas("address", "here"), + "
here
", + "Expected:
here
", + ) + self.assertEqual( + crear_etiquetas("body", "Heart"), + "Heart", + "Expected: Heart", + ) + self.assertEqual(crear_etiquetas("i", "i"), "i", "Expected: i") + self.assertEqual(crear_etiquetas("i", ""), "", "Expected: ") + + + myTests().main() + + + .. tab:: Exercise 7 + + .. activecode:: q7_7_en + :nocodelens: + + Develop the function ``repetir_letras`` that receives a string ``s`` of at least two characters and returns a new string with the last two letters repeated three times |br| |br| + Examples: |br| + ``repetir_letras("Hello")`` -> ``"lololo"`` |br| + ``repetir_letras("abb")`` -> ``"bbbbbb"`` |br| + ``repetir_letras("Hi")`` -> ``"HiHiHi"`` |br| + + ~~~~ + def repetir_letras(s): + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(repetir_letras("Hello"), "lololo", "Expected: lololo") + self.assertEqual(repetir_letras("ab"), "ababab", "Expected: ababab") + self.assertEqual(repetir_letras("Hi"), "HiHiHi", "Expected: HiHiHi") + self.assertEqual(repetir_letras("Candy"), "dydydy", "Expected: dydydy") + self.assertEqual(repetir_letras("Code"), "dedede", "Expected: dedede") + + + myTests().main() + + + .. tab:: Exercise 8 + + .. activecode:: q7_8_en + :nocodelens: + + Develop the function ``otra_repetir_letras`` (variation of the Exercise 7 function) that receives a string ``s`` of at least two characters and a positive integer ``n`` and returns a new string with the last two letters repeated ``n`` times |br| |br| + Examples: |br| + ``otra_repetir_letras("Hello", 3)`` -> ``"lololo"`` |br| + ``otra_repetir_letras("abb", 1)`` -> ``"bb"`` |br| + ``otra_repetir_letras("Hi", 5)`` -> ``"HiHiHiHiHi"`` |br| + + ~~~~ + def otra_repetir_letras(s, n): + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(otra_repetir_letras("Hello", 3), "lololo", "Expected: lololo") + self.assertEqual(otra_repetir_letras("ab", 2), "abab", "Expected: abab") + self.assertEqual(otra_repetir_letras("Hi", 6), "HiHiHiHiHiHi", "Expected: HiHiHi") + self.assertEqual(otra_repetir_letras("Candy", 1), "dy", "Expected: dy") + self.assertEqual(otra_repetir_letras("Code", 0), "", "Expected: ''") + + + myTests().main() + + + .. tab:: Exercise 9 + + .. activecode:: q7_9_en + :nocodelens: + + Develop the function ``primera_mitad`` that receives a string ``s`` and returns the first half of the original string |br| |br| + Examples:|br| + ``primera_mitad("WooHoo")`` -> ``"Woo"`` |br| + ``primera_mitad("HelloThere")`` -> ``"Hello"`` |br| + ``primera_mitad("abcdef")`` -> ``"abc"`` |br| + + ~~~~ + def primera_mitad(s): + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(primera_mitad("WooHoo"), "Woo", "Expected: Woo") + self.assertEqual(primera_mitad("HelloThere"), "Hello", "Expected: Hello") + self.assertEqual(primera_mitad("abcdef"), "abc", "Expected: abc") + self.assertEqual(primera_mitad(""), "", "Expected: ") + self.assertEqual(primera_mitad("ab"), "a", "Expected: a") + self.assertEqual(primera_mitad("0123456789"), "01234", "Expected: 01234") + self.assertEqual(primera_mitad("kitten"), "kit", "Expected: kit") + + + myTests().main() + + .. tab:: Exercise 10 + + .. activecode:: q7_10_en + :nocodelens: + + + Develop the function ``remove_first_last`` that receives a string ``s`` of at least two characters and returns a string without the first or last character. |br| |br| + Examples: |br| + ``remove_first_last("Hello")`` -> ``"ell"`` |br| + ``remove_first_last("python")`` -> ``"ytho"`` |br| + ``remove_first_last("coding")`` -> ``"odin"`` |br| + + ~~~~ + def remove_first_last(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(remove_first_last("Hello"), "ell", "Expected: ell") + self.assertEqual(remove_first_last("Python"), "ytho", "Expected: ytho") + self.assertEqual( + remove_first_last("coding"), "odin", "Expected: odin" + ) + self.assertEqual(remove_first_last("code"), "od", "Expected: od") + self.assertEqual(remove_first_last("ab"), "", "Expected: ") + self.assertEqual( + remove_first_last(" PyZombies "), + "PyZombies", + "Expected: PyZombies", + ) + self.assertEqual( + remove_first_last("Chocolate!"), + "hocolate", + "Expected: hocolate", + ) + self.assertEqual(remove_first_last("kitten"), "itte", "Expected: itte") + self.assertEqual(remove_first_last("woohoo"), "ooho", "Expected: ooho") + + + myTests().main() + + + .. tab:: Exercise 11 + + .. activecode:: q7_11_en + :nocodelens: + + + Develop the function ``rotate_left_2`` that receives a string ``s`` of at least two characters and returns the original string rotated 2 positions to the left. |br| |br| + Examples: |br| + ``rotate_left_2("Hello")`` -> ``"lloHe"`` |br| + ``rotate_left_2("Hi")`` -> ``"Hi"`` |br| + + ~~~~ + def rotate_left_2(s): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual( + rotate_left_2("Hello"), "lloHe", "Expected: lloHe" + ) + self.assertEqual( + rotate_left_2("python"), "thonpy", "Expected: thonpy" + ) + self.assertEqual(rotate_left_2("Hi"), "Hi", "Expected: Hi") + self.assertEqual(rotate_left_2("code"), "deco", "Expected: deco") + self.assertEqual(rotate_left_2("cat"), "tca", "Expected: tca") + self.assertEqual( + rotate_left_2("12345"), "34512", "Expected: 34512" + ) + self.assertEqual( + rotate_left_2("Chocolate"), + "ocolateCh", + "Expected: ocolateCh", + ) + self.assertEqual( + rotate_left_2("bricks"), "icksbr", "Expected: icksbr" + ) + self.assertEqual( + rotate_left_2("isPyzomb"), + "PyZombies", + "Expected: PyZombies", + ) + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz8.rst.txt b/293/_sources/quiz/Quiz8.rst.txt new file mode 100644 index 0000000000..06bf0a90b1 --- /dev/null +++ b/293/_sources/quiz/Quiz8.rst.txt @@ -0,0 +1,508 @@ +========= +Quiz - 8 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz8 + + .. tab:: Ejercicio 1 + + .. activecode:: q8_1 + :nocodelens: + + Defina una función ``primer_o_ultimo_6`` que compruebe si 6 es el primer + o el último elemento en la lista de números ``numeros`` que se le pase como parámetro. + Si lo es, devolver ``True``, de lo contrario devolver ``False``. |br| |br| + Ejemplos: |br| + ``primer_o_ultimo_6([1, 2, 6])`` -> ``True`` |br| + ``primer_o_ultimo_6([6, 1, 2, 3])`` -> ``True`` |br| + ``primer_o_ultimo_6([3, 2, 1])`` -> ``False`` |br| + + ~~~~ + def primer_o_ultimo_6(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(primer_o_ultimo_6([1, 2, 6]), True, "Esperado: True") + self.assertEqual(primer_o_ultimo_6([3, 6]), True, "Esperado: True") + self.assertEqual(primer_o_ultimo_6([3, 6]), True, "Esperado: True") + self.assertEqual(primer_o_ultimo_6([3]), False, "Esperado: False") + self.assertEqual(primer_o_ultimo_6([6, 1, 2, 3]), True, "Esperado: True") + self.assertEqual(primer_o_ultimo_6([3, 2, 1]), False, "Esperado: False") + self.assertEqual(primer_o_ultimo_6([3, 6, 1]), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q8_2 + :nocodelens: + + Defina una función ``extremos_iguales`` que tome una lista ``numeros`` como parámetro, + y regrese ``True`` si la lista de números tiene al menos un elemento y el + primer elemento es igual al último. De lo contrario devolver ``False``. |br| |br| + Ejemplos: |br| + ``extremos_iguales([1, 2, 3])`` -> ``False`` |br| + ``extremos_iguales([1, 2, 3, 1])`` -> ``True`` |br| + ``extremos_iguales([1, 2, 1])`` -> ``True`` |br| + + ~~~~ + def extremos_iguales(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(extremos_iguales([1, 2, 3]), False, "Esperado: False") + self.assertEqual(extremos_iguales([1, 2, 1]), True, "Esperado: True") + self.assertEqual(extremos_iguales([7]), True, "Esperado: True") + self.assertEqual(extremos_iguales([]), False, "Esperado: False") + self.assertEqual(extremos_iguales([7, 7]), True, "Esperado: True") + self.assertEqual( + extremos_iguales([1, 2, 3, 1]), + True, + "Esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q8_3 + :nocodelens: + + Defina una función ``extremo_comun`` que tome dos listas ``a`` y ``b`` + como parámetros, y verifique que los dos primeros números de ambas listas + son iguales o que los dos últimos números de ambas listas son iguales. + Suponga que ambas listas tienen por lo menos un elemento. |br| |br| + Ejemplos: |br| + ``extremo_comun([1, 2, 3], [7, 3])`` -> ``True`` |br| + ``extremo_comun([1, 2, 3], [7, 3, 2])`` -> ``False`` |br| + ``extremo_comun([1, 2, 3], [1, 3])`` -> ``True`` |br| + + ~~~~ + def extremo_comun(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(extremo_comun([1, 2, 3], [1]), True, "Esperado: True") + self.assertEqual( + extremo_comun([1, 2, 3], [2]), + False, + "Esperado: False" + ) + self.assertEqual( + extremo_comun([1, 2, 3], [7, 3]), + True, + "Esperado: True" + ) + self.assertEqual( + extremo_comun([1, 2, 3], [7, 3, 2]), + False, + "Esperado: False" + ) + self.assertEqual( + extremo_comun([1, 2, 3], [1, 3]), + True, + "Esperado: True" + ) + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q8_4 + :nocodelens: + + Defina una función ``mayor_extremo`` que tome la lista ``numeros`` como parámetro, + compare los extremos de la lista y regrese una nueva lista del mismo tamaño + donde todos los elementos son el extremo de mayor magnitud. |br| |br| + Ejemplos: |br| + ``mayor_extremo([1, 2, 3])`` -> ``[3, 3, 3]`` |br| + ``mayor_extremo([1, 3, 2])`` -> ``[2, 2, 2]`` |br| + + ~~~~ + def mayor_extremo(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual( + mayor_extremo([1, 2, 3]), + [3, 3, 3], + "Esperado: [3,3,3]" + ) + self.assertEqual( + mayor_extremo([11, 5, 9]), + [11, 11, 11], + "Esperado: [11,11,11]" + ) + self.assertEqual( + mayor_extremo([2, 11, 3]), + [3, 3, 3], + "Esperado: [3,3,3]" + ) + self.assertEqual( + mayor_extremo([11, 3, 3]), + [11, 11, 11], + "Esperado: [11,11,11]" + ) + self.assertEqual( + mayor_extremo([3, 11, 11]), + [11, 11, 11], + "Esperado: [11,11,11]" + ) + self.assertEqual( + mayor_extremo([2, 2, 2]), + [2, 2, 2], + "Esperado: [2,2,2]" + ) + self.assertEqual( + mayor_extremo([2, 11, 2]), + [2, 2, 2], + "Esperado: [2,2,2]" + ) + self.assertEqual( + mayor_extremo([0, 0, 1]), + [1, 1, 1], + "Esperado: [1,1,1]" + ) + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q8_5 + :nocodelens: + + Defina una función ``sumar_primeros_dos`` que tome la lista ``numeros`` + de número enteros de cualquier tamaño como parámetro, y regrese la suma + de los dos primeros elementos. Si la lista tiene menos de dos elementos, sume 0s. |br| |br| + Ejemplos: |br| + ``sumar_primeros_dos([1, 2, 3])`` -> ``3`` |br| + ``sumar_primeros_dos([1, 1])`` -> ``2`` |br| + ``sumar_primeros_dos([])`` -> ``0`` |br| + + ~~~~ + def sumar_primeros_dos(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(sumar_primeros_dos([1, 2, 3]), 3, "Esperado: 3") + self.assertEqual(sumar_primeros_dos([1, 1]), 2, "Esperado: 2") + self.assertEqual(sumar_primeros_dos([1, 1, 1, 1]), 2, "Esperado: 2") + self.assertEqual(sumar_primeros_dos([1, 2]), 3, "Esperado: 3") + self.assertEqual(sumar_primeros_dos([1]), 1, "Esperado: 1") + self.assertEqual(sumar_primeros_dos([]), 0, "Esperado: 0") + self.assertEqual(sumar_primeros_dos([4, 5, 6]), 9, "Esperado: 9") + self.assertEqual(sumar_primeros_dos([4]), 4, "Esperado: 4") + self.assertEqual(sumar_primeros_dos([4, -12, 5]), -8, "Esperado: -8") + self.assertEqual( + sumar_primeros_dos([-200, 35, 10, 8]), + -165, + "Esperado: -165" + ) + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q8_6 + :nocodelens: + + Defina una función ``al_medio`` que tome dos listas ``a`` y ``b`` de + números enteros como parámetros, y regrese una lista de tamaño 2 que + contenga los elementos de en medio de ``a`` y ``b``. Suponga que las listas + tienen un tamaño impar. |br| |br| + Ejemplos: |br| + ``al_medio([1, 2, 3], [4, 5, 6])`` -> ``[2, 5]`` |br| + ``al_medio([7, 7, 7], [3, 8, 0])`` -> ``[7, 8]`` |br| + ``al_medio([5, 2, 9], [1, 4, 5])`` -> ``[2, 4]`` |br| + + ~~~~ + def al_medio(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual( + al_medio([1, 2, 3], [4, 5, 6]), + [2, 5], + "Esperado: [2,5]" + ) + self.assertEqual( + al_medio([7, 7, 7], [3, 8, 0]), + [7, 8], + "Esperado: [7,8]" + ) + self.assertEqual( + al_medio([5, 2, 9], [1, 4, 5]), + [2, 4], + "Esperado: [2,4]" + ) + self.assertEqual( + al_medio([1, 9, 7], [4, 8, 8]), + [9, 8], + "Esperado: [9,8]" + ) + self.assertEqual( + al_medio([1, 2, 3, 10, 2], [3, 1, 4]), + [3, 1], + "Esperado: [2,1]" + ) + self.assertEqual( + al_medio([1, 2, -2, 4, 1], [1]), + [-2, 1], + "Esperado: [2,1]" + ) + + + myTests().main() + + + .. tab:: Ejercicio 7 + + .. activecode:: q8_7 + :nocodelens: + + Define una función ``cita_de_lujo``. La función tomará dos parámetros + ``mi_punt`` y ``pareja_punt``. Suponga que va un restaurante con su pareja. + Los parámetros representan la puntuación de la ropa que llevan puesta del 0 al 10. + Cuanto más alto es el puntaje, más elegante se han vestido. El puntaje de su ropa + determinará si les dan una mesa en el restaurante o no, de acuerdo a las siguientes reglas:|br| + + - Si la puntuación de la ropa de uno de los dos es menor o igual a 2, + no tendrán derecho a una mesa (``0``). |br| + - Si las calificaciones son más altas, entonces si una de las dos es muy + elegante (puntuación >= 8) sí tendrán derecho a mesa (``2``). |br| + - De lo contrario, la respuesta es tal vez (``1``). |br| + + Entonces ``cita_de_lujo`` devuelve un número entre 0, 1 y 2 que significan No, Tal vez y Si respectivamente |br| |br| + Ejemplos: |br| + ``cita_de_lujo(5, 10)`` -> ``2`` |br| + ``cita_de_lujo(5, 2)`` -> ``0`` |br| + ``cita_de_lujo(5, 5)`` -> ``1`` |br| + + ~~~~ + def cita_de_lujo(mi_punt, pareja_punt): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(cita_de_lujo(5, 10), 2, "Esperado: 2") + self.assertEqual(cita_de_lujo(5, 2), 0, "Esperado: 0") + self.assertEqual(cita_de_lujo(5, 5), 1, "Esperado: 1") + self.assertEqual(cita_de_lujo(3, 3), 1, "Esperado: 1") + self.assertEqual(cita_de_lujo(10, 2), 0, "Esperado: 0") + self.assertEqual(cita_de_lujo(2, 9), 0, "Esperado: 0") + self.assertEqual(cita_de_lujo(9, 9), 2, "Esperado: 2") + self.assertEqual(cita_de_lujo(10, 5), 2, "Esperado: 2") + self.assertEqual(cita_de_lujo(2, 2), 0, "Esperado: 0") + self.assertEqual(cita_de_lujo(3, 7), 1, "Esperado: 1") + self.assertEqual(cita_de_lujo(2, 7), 0, "Esperado: 0") + self.assertEqual(cita_de_lujo(6, 2), 0, "Esperado: 0") + + + myTests().main() + + + .. tab:: Ejercicio 8 + + .. activecode:: q8_8 + :nocodelens: + + El equipo de fútbol *ardillas* normalmente juega cuando la temperatura + está entre 60 y 90 grados Fahrenheit, pero cuando es verano la temperatura + superior a la que juegan las *ardillas* es de 100 grados Fahrenheit en lugar de 90. + Defina una función ``juegan_ardillas`` que tome 2 parámetros, ``temp`` representando + la temperatura, y ``es_verano``, que puede ser ``True`` si es verano o ``False`` si no lo es. + La función debe regresar ``True`` si las *ardillas* juegan o ``False`` si no. |br| |br| + Ejemplos: |br| + ``juegan_ardillas(70, False)`` -> ``True`` |br| + ``juegan_ardillas(95, False)`` -> ``False`` |br| + ``juegan_ardillas(95, True)`` -> ``True`` |br| + + ~~~~ + def juegan_ardillas(temp, es_verano): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(juegan_ardillas(70, False), True, "Esperado: True") + self.assertEqual(juegan_ardillas(95, False), False, "Esperado: False") + self.assertEqual(juegan_ardillas(95, True), True, "Esperado: True") + self.assertEqual(juegan_ardillas(90, False), True, "Esperado: True") + self.assertEqual(juegan_ardillas(90, True), True, "Esperado: True") + self.assertEqual(juegan_ardillas(50, False), False, "Esperado: False") + self.assertEqual(juegan_ardillas(50, True), False, "Esperado: True") + self.assertEqual(juegan_ardillas(100, False), False, "Esperado: False") + self.assertEqual(juegan_ardillas(100, True), True, "Esperado: True") + self.assertEqual(juegan_ardillas(105, True), False, "Esperado: True") + self.assertEqual(juegan_ardillas(59, False), False, "Esperado: False") + self.assertEqual(juegan_ardillas(59, True), False, "Esperado: True") + self.assertEqual(juegan_ardillas(60, False), True, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 9 + + .. activecode:: q8_9 + :nocodelens: + + Simulemos un velocímetro que te aplica una multa en caso de exceder la velociad máxima: + + - Velocidad <= 60: sin multa |br| + - Velocidad entre 61 y 80: multa media |br| + - Velocidad superior a 80: multa severa |br| + + Si es tu cumpleaños la velocidad puede ser 5 km/h mayor en todos los casos. |br| + Defina una función ``aplicar_multa`` que reciba como parámetros a ``velocidad`` y + ``cumplo_anios``. El primero representa la velocidad a la que ibas, y el segundo + puede ser ``True`` si es tu cumpleaños o ``False`` si no lo es. Esta función debe + regresar 0, 1 o 2 de acuerdo a lo siguiente: |br| + + - sin multa = 0 |br| + - multa media = 1 |br| + - multa severa = 2 |br| |br| + + Ejemplos: |br| + ``aplicar_multa(60, False)`` -> ``0`` |br| + ``aplicar_multa(65, False)`` -> ``1`` |br| + ``aplicar_multa(65, True)`` -> ``0`` |br| + ``aplicar_multa(80, False)`` -> ``1`` |br| + + ~~~~ + def aplicar_multa(velocidad, cumplo_anios): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(aplicar_multa(20, False), 0, "Esperado: 0") + self.assertEqual(aplicar_multa(20, True), 0, "Esperado: 0") + self.assertEqual(aplicar_multa(60, False), 0, "Esperado: 0") + self.assertEqual(aplicar_multa(65, False), 1, "Esperado: 1") + self.assertEqual(aplicar_multa(65, True), 0, "Esperado: 0") + self.assertEqual(aplicar_multa(80, False), 1, "Esperado: 1") + self.assertEqual(aplicar_multa(85, False), 2, "Esperado: 2") + self.assertEqual(aplicar_multa(85, True), 1, "Esperado: 1") + self.assertEqual(aplicar_multa(70, False), 1, "Esperado: 1") + self.assertEqual(aplicar_multa(75, False), 1, "Esperado: 1") + self.assertEqual(aplicar_multa(75, True), 1, "Esperado: 1") + self.assertEqual(aplicar_multa(40, False), 0, "Esperado: 0") + self.assertEqual(aplicar_multa(40, True), 0, "Esperado: 0") + self.assertEqual(aplicar_multa(90, False), 2, "Esperado: 2") + self.assertEqual(aplicar_multa(90, True), 2, "Esperado: 2") + + + myTests().main() + + + .. tab:: Ejercicio 10 + + .. activecode:: q8_10 + :nocodelens: + + Defina una función ``poner_alarma`` que tome dos parámetros: El primer parámetro + ``dia`` es un número del 0-6 que representa un día de la semana de acuerdo a lo siguiente: |br| + día: 0 = domingo, 1 = lunes, 2 = martes, ..., 6 = sábado. |br| + El segundo parámetro ``vacaciones`` tomará el valor ``True`` si estás de vacaciones o + ``False`` si no lo estás. La función regresará un string que indica cuándo sonará + el despertador de acuerdo a lo siguiente: |br| + + - Días de la semana: '07:00' |br| + - Fines de semana: '10:00' |br| + + A menos que esté de vacaciones, en este caso: |br| + + - Días de la semana: '10:00' |br| + - Fines de semana: 'libre' |br| |br| + + Ejemplos: |br| + ``poner_alarma(1, False)`` -> ``"7:00"`` |br| + ``poner_alarma(1, True)`` -> ``"10:00"`` |br| + ``poner_alarma(6, True)`` -> ``"libre"`` |br| + ``poner_alarma(0, False)`` -> ``"10:00"`` |br| + + ~~~~ + def poner_alarma(dia, vacaciones): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(poner_alarma(1, False), "7:00", "Esperado: 7:00") + self.assertEqual(poner_alarma(5, False), "7:00", "Esperado: 7:00") + self.assertEqual(poner_alarma(0, False), "10:00", "Esperado: 10:00") + self.assertEqual(poner_alarma(6, False), "10:00", "Esperado: 10:00") + self.assertEqual(poner_alarma(0, True), "libre", "Esperado: libre") + self.assertEqual(poner_alarma(6, True), "libre", "Esperado: libre") + self.assertEqual(poner_alarma(1, True), "10:00", "Esperado: 10:00") + self.assertEqual(poner_alarma(3, True), "10:00", "Esperado: 10:00") + self.assertEqual(poner_alarma(5, True), "10:00", "Esperado: 10:00") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz8_en.rst.txt b/293/_sources/quiz/Quiz8_en.rst.txt new file mode 100644 index 0000000000..186ac9c865 --- /dev/null +++ b/293/_sources/quiz/Quiz8_en.rst.txt @@ -0,0 +1,499 @@ +========= +Quiz - 8 +========= + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz8 + + .. tab:: Exercise 1 + + .. activecode:: q8_1_en + :nocodelens: + + Define a function ``first_or_last_6`` that checks whether 6 is the first + or the last element in the list of numbers ``numbers`` passed as a parameter. + If it is, return ``True``, otherwise return ``False``. |br| |br| + Examples: |br| + ``first_or_last_6([1, 2, 6])`` -> ``True`` |br| + ``first_or_last_6([6, 1, 2, 3])`` -> ``True`` |br| + ``first_or_last_6([3, 2, 1])`` -> ``False`` |br| + + ~~~~ + def first_or_last_6(numbers): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(first_or_last_6([1, 2, 6]), True, "Expected: True") + self.assertEqual(first_or_last_6([3, 6]), True, "Expected: True") + self.assertEqual(first_or_last_6([3, 6]), True, "Expected: True") + self.assertEqual(first_or_last_6([3]), False, "Expected: False") + self.assertEqual(first_or_last_6([6, 1, 2, 3]), True, "Expected: True") + self.assertEqual(first_or_last_6([3, 2, 1]), False, "Expected: False") + self.assertEqual(first_or_last_6([3, 6, 1]), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: q8_2_en + :nocodelens: + + Define a function ``same_ends`` that takes a list ``numbers`` as a parameter, + and returns ``True`` if the list of numbers has at least one element and the + first element is the same as the last. Otherwise, return ``False``. |br| |br| + Examples: |br| + ``same_ends([1, 2, 3])`` -> ``False`` |br| + ``same_ends([1, 2, 3, 1])`` -> ``True`` |br| + ``same_ends([1, 2, 1])`` -> ``True`` |br| + + ~~~~ + def same_ends(numbers): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(same_ends([1, 2, 3]), False, "Expected: False") + self.assertEqual(same_ends([1, 2, 1]), True, "Expected: True") + self.assertEqual(same_ends([7]), True, "Expected: True") + self.assertEqual(same_ends([]), False, "Expected: False") + self.assertEqual(same_ends([7, 7]), True, "Expected: True") + self.assertEqual( + same_ends([1, 2, 3, 1]), + True, + "Expected: True") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: q8_3_en + :nocodelens: + + Define a function ``common_ends`` that takes two lists ``a`` and ``b`` + as parameters, and checks that the first two numbers of both lists are equal + or that the last two numbers of both lists are equal. Assume both lists have + at least one element. |br| |br| + Examples: |br| + ``common_ends([1, 2, 3], [7, 3])`` -> ``True`` |br| + ``common_ends([1, 2, 3], [7, 3, 2])`` -> ``False`` |br| + ``common_ends([1, 2, 3], [1, 3])`` -> ``True`` |br| + + ~~~~ + def common_ends(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(common_ends([1, 2, 3], [1]), True, "Expected: True") + self.assertEqual( + common_ends([1, 2, 3], [2]), + False, + "Expected: False" + ) + self.assertEqual( + common_ends([1, 2, 3], [7, 3]), + True, + "Expected: True" + ) + self.assertEqual( + common_ends([1, 2, 3], [7, 3, 2]), + False, + "Expected: False" + ) + self.assertEqual( + common_ends([1, 2, 3], [1, 3]), + True, + "Expected: True" + ) + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: q8_4_en + :nocodelens: + + Define a function called ``mayor_extremo`` that takes the list "numeros" as parameter, compares the ends of the list and returns a new list of the same size where all elements are the greatest magnitude extreme. |br| |br| + Examples: |br| + ``mayor_extremo([1, 2, 3])`` -> ``[3, 3, 3]`` |br| + ``mayor_extremo([1, 3, 2])`` -> ``[2, 2, 2]`` |br| + + ~~~~ + def mayor_extremo(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual( + mayor_extremo([1, 2, 3]), + [3, 3, 3], + "Expected: [3,3,3]" + ) + self.assertEqual( + mayor_extremo([11, 5, 9]), + [11, 11, 11], + "Expected: [11,11,11]" + ) + self.assertEqual( + mayor_extremo([2, 11, 3]), + [3, 3, 3], + "Expected: [3,3,3]" + ) + self.assertEqual( + mayor_extremo([11, 3, 3]), + [11, 11, 11], + "Expected: [11,11,11]" + ) + self.assertEqual( + mayor_extremo([3, 11, 11]), + [11, 11, 11], + "Expected: [11,11,11]" + ) + self.assertEqual( + mayor_extremo([2, 2, 2]), + [2, 2, 2], + "Expected: [2,2,2]" + ) + self.assertEqual( + mayor_extremo([2, 11, 2]), + [2, 2, 2], + "Expected: [2,2,2]" + ) + self.assertEqual( + mayor_extremo([0, 0, 1]), + [1, 1, 1], + "Expected: [1,1,1]" + ) + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q8_5_en + :nocodelens: + + Define a function called ``sumar_primeros_dos`` that takes the integer list ``numeros`` of any length as parameter and returns the sum of the first two elements. If the list has less than two elements, add 0s. |br| |br| + Examples: |br| + ``sumar_primeros_dos([1, 2, 3])`` -> ``3`` |br| + ``sumar_primeros_dos([1, 1])`` -> ``2`` |br| + ``sumar_primeros_dos([])`` -> ``0`` |br| + + ~~~~ + def sumar_primeros_dos(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(sumar_primeros_dos([1, 2, 3]), 3, "Expected: 3") + self.assertEqual(sumar_primeros_dos([1, 1]), 2, "Expected: 2") + self.assertEqual(sumar_primeros_dos([1, 1, 1, 1]), 2, "Expected: 2") + self.assertEqual(sumar_primeros_dos([1, 2]), 3, "Expected: 3") + self.assertEqual(sumar_primeros_dos([1]), 1, "Expected: 1") + self.assertEqual(sumar_primeros_dos([]), 0, "Expected: 0") + self.assertEqual(sumar_primeros_dos([4, 5, 6]), 9, "Expected: 9") + self.assertEqual(sumar_primeros_dos([4]), 4, "Expected: 4") + self.assertEqual(sumar_primeros_dos([4, -12, 5]), -8, "Expected: -8") + self.assertEqual( + sumar_primeros_dos([-200, 35, 10, 8]), + -165, + "Expected: -165" + ) + + + myTests().main() + + + .. tab:: Exercise 6 + + .. activecode:: q8_6_en + :nocodelens: + + Define a function called ``al_medio`` that takes two integer lists ``a`` and ``b`` as parameters, and returns a list of size 2 that contains the middle elements of ``a`` and ``b``. Assume that the lists have an odd length. |br| |br| + Examples: |br| + ``al_medio([1, 2, 3], [4, 5, 6])`` -> ``[2, 5]`` |br| + ``al_medio([7, 7, 7], [3, 8, 0])`` -> ``[7, 8]`` |br| + ``al_medio([5, 2, 9], [1, 4, 5])`` -> ``[2, 4]`` |br| + + ~~~~ + def al_medio(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual( + al_medio([1, 2, 3], [4, 5, 6]), + [2, 5], + "Expected: [2,5]" + ) + self.assertEqual( + al_medio([7, 7, 7], [3, 8, 0]), + [7, 8], + "Expected: [7,8]" + ) + self.assertEqual( + al_medio([5, 2, 9], [1, 4, 5]), + [2, 4], + "Expected: [2,4]" + ) + self.assertEqual( + al_medio([1, 9, 7], [4, 8, 8]), + [9, 8], + "Expected: [9,8]" + ) + self.assertEqual( + al_medio([1, 2, 3, 10, 2], [3, 1, 4]), + [3, 1], + "Expected: [2,1]" + ) + self.assertEqual( + al_medio([1, 2, -2, 4, 1], [1]), + [-2, 1], + "Expected: [2,1]" + ) + + + myTests().main() + + .. tab:: Exercise 7 + + .. activecode:: q8_7_en + :nocodelens: + + Define a function ``fancy_date``. The function will take two parameters, + ``my_score`` and ``partner_score``. Assume that you are going to a + restaurant with your partner. The parameters represent the score of the clothes + you are wearing from 0 to 10. The higher the score, the more elegant you are dressed. + Your clothes score will determine if you get a table at the restaurant or not, according to the following rules: |br| + + - If the score of one of the two clothing is less than or equal to 2, + they will not be entitled to a table (``0``). |br| + - If the scores are higher, then if one of them is very + elegant (score >= 8) they will be entitled to a table (``2``). |br| + - Otherwise, the answer is maybe (``1``). |br| + + + So ``fancy_date`` returns a number between 0, 1, and 2, which mean No, Maybe, and Yes, respectively. |br| |br| + Examples: |br| + ``fancy_date(5, 10)`` -> ``2`` |br| + ``fancy_date(5, 2)`` -> ``0`` |br| + ``fancy_date(5, 5)`` -> ``1`` |br| + + ~~~~ + def fancy_date(my_score, partner_score): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(fancy_date(5, 10), 2, "Expected: 2") + self.assertEqual(fancy_date(5, 2), 0, "Expected: 0") + self.assertEqual(fancy_date(5, 5), 1, "Expected: 1") + self.assertEqual(fancy_date(3, 3), 1, "Expected: 1") + self.assertEqual(fancy_date(10, 2), 0, "Expected: 0") + self.assertEqual(fancy_date(2, 9), 0, "Expected: 0") + self.assertEqual(fancy_date(9, 9), 2, "Expected: 2") + self.assertEqual(fancy_date(10, 5), 2, "Expected: 2") + self.assertEqual(fancy_date(2, 2), 0, "Expected: 0") + self.assertEqual(fancy_date(3, 7), 1, "Expected: 1") + self.assertEqual(fancy_date(2, 7), 0, "Expected: 0") + self.assertEqual(fancy_date(6, 2), 0, "Expected: 0") + + + myTests().main() + + .. tab:: Exercise 8 + + .. activecode:: q8_8_en + :nocodelens: + + The *squirrels* soccer team normally plays when the temperature is + between 60 and 90 degrees Fahrenheit. But in summer, the temperature exceeds + the maximum temperature they will play, which is 90 degrees Fahrenheit. + Define a function ``squirrel_play`` that takes 2 parameters, ``temp`` representing + the temperature, and ``is_summer``, which can be ``True`` if it's summer or ``False`` + if not. The function should return ``True`` if the *squirrels* play or ``False`` if they don't. |br| |br| + Examples: |br| + ``squirrel_play(70, False)`` -> ``True`` |br| + ``squirrel_play(95, False)`` -> ``False`` |br| + ``squirrel_play(95, True)`` -> ``True`` |br| + + ~~~~ + def squirrel_play(temp, is_summer): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(squirrel_play(70, False), True, "Expected: True") + self.assertEqual(squirrel_play(95, False), False, "Expected: False") + self.assertEqual(squirrel_play(95, True), True, "Expected: True") + self.assertEqual(squirrel_play(90, False), True, "Expected: True") + self.assertEqual(squirrel_play(90, True), True, "Expected: True") + self.assertEqual(squirrel_play(50, False), False, "Expected: False") + self.assertEqual(squirrel_play(50, True), False, "Expected: True") + self.assertEqual(squirrel_play(100, False), False, "Expected: False") + self.assertEqual(squirrel_play(100, True), True, "Expected: True") + self.assertEqual(squirrel_play(105, True), False, "Expected: True") + self.assertEqual(squirrel_play(59, False), False, "Expected: False") + self.assertEqual(squirrel_play(59, True), False, "Expected: True") + self.assertEqual(squirrel_play(60, False), True, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 9 + + .. activecode:: q8_9_en + :nocodelens: + + Let's simulate a speedometer that applies a fine if the maximum speed is exceeded: + + - Speed <= 60: no fine |br| + - Speed between 61 and 80: medium fine |br| + - Speed above 80: severe fine |br| + + If it's your birthday, the speed can be 5 km/h higher in all cases. |br| + Define a function ``apply_fine`` that takes the parameters ``speed`` and + ``birthday``. The first represents the speed you were going, and the second + can be ``True`` if it's your birthday or ``False`` if it's not. This function should + return 0, 1 or 2 according to the following: |br| + + - no fine = 0 |br| + - medium fine = 1 |br| + - severe fine = 2 |br| |br| + + Examples: |br| + ``apply_fine(60, False)`` -> ``0`` |br| + ``apply_fine(65, False)`` -> ``1`` |br| + ``apply_fine(65, True)`` -> ``0`` |br| + ``apply_fine(80, False)`` -> ``1`` |br| + + ~~~~ + def apply_fine(speed, birthday): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + + def testOne(self): + self.assertEqual(apply_fine(20, False), 0, "Expected: 0") + self.assertEqual(apply_fine(20, True), 0, "Expected: 0") + self.assertEqual(apply_fine(60, False), 0, "Expected: 0") + self.assertEqual(apply_fine(65, False), 1, "Expected: 1") + self.assertEqual(apply_fine(65, True), 0, "Expected: 0") + self.assertEqual(apply_fine(80, False), 1, "Expected: 1") + self.assertEqual(apply_fine(85, False), 2, "Expected: 2") + self.assertEqual(apply_fine(85, True), 1, "Expected: 1") + self.assertEqual(apply_fine(70, False), 1, "Expected: 1") + self.assertEqual(apply_fine(75, False), 1, "Expected: 1") + self.assertEqual(apply_fine(75, True), 1, "Expected: 1") + self.assertEqual(apply_fine(40, False), 0, "Expected: 0") + self.assertEqual(apply_fine(40, True), 0, "Expected: 0") + self.assertEqual(apply_fine(90, False), 2, "Expected: 2") + self.assertEqual(apply_fine(90, True), 2, "Expected: 2") + + + myTests().main() + + + .. tab:: Exercise 10 + + .. activecode:: q8_10_en + :nocodelens: + + Define a function ``set_alarm`` that takes two parameters: The first parameter + ``day`` is a number from 0-6 that represents a day of the week according to the following: |br| + day: 0 = Sunday, 1 = Monday, 2 = Tuesday, ..., 6 = Saturday. |br| + The second parameter ``vacation`` will be set to ``True`` if you're on vacation or + ``False`` if you're not. The function will return a string that indicates when + the alarm clock will ring according to the following: |br| + + - Weekdays: '07:00' |br| + - Weekends: '10:00' |br| + + Unless you're on vacation, in which case: |br| + + - Weekdays: '10:00' |br| + - Weekends: 'off' |br| |br| + + Examples: |br| + ``set_alarm(1, False)`` -> ``"7:00"`` |br| + ``set_alarm(1, True)`` -> ``"10:00"`` |br| + ``set_alarm(6, True)`` -> ``"off"`` |br| + ``set_alarm(0, False)`` -> ``"10:00"`` |br| + + ~~~~ + def set_alarm(day, vacation): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(set_alarm(1, False), "7:00", "Expected: 7:00") + self.assertEqual(set_alarm(5, False), "7:00", "Expected: 7:00") + self.assertEqual(set_alarm(0, False), "10:00", "Expected: 10:00") + self.assertEqual(set_alarm(6, False), "10:00", "Expected: 10:00") + self.assertEqual(set_alarm(0, True), "off", "Expected: off") + self.assertEqual(set_alarm(6, True), "off", "Expected: off") + self.assertEqual(set_alarm(1, True), "10:00", "Expected: 10:00") + self.assertEqual(set_alarm(3, True), "10:00", "Expected: 10:00") + self.assertEqual(set_alarm(5, True), "10:00", "Expected: 10:00") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/Quiz9.rst.txt b/293/_sources/quiz/Quiz9.rst.txt new file mode 100644 index 0000000000..ee57afcea0 --- /dev/null +++ b/293/_sources/quiz/Quiz9.rst.txt @@ -0,0 +1,523 @@ +======== +Quiz - 9 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz9 + + .. tab:: Ejercicio 1 + + .. activecode:: q9_1 + :nocodelens: + + Desarrolle la función ``cerca_de_10`` que recibe un entero ``n`` y devuelve ``True`` cuando ``n`` sea múltiplo de 10, o cuando ``n`` esté a una o dos unidades de serlo. En caso contrario devuelva ``False``. |br| |br| + Ejemplos: |br| + ``cerca_de_10(12)`` -> ``True`` |br| + ``cerca_de_10(17)`` -> ``False`` |br| + ``cerca_de_10(19)`` -> ``True`` |br| + + ~~~~ + def cerca_de_10(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(cerca_de_10(12), True, "Esperado: True") + self.assertEqual(cerca_de_10(17), False, "Esperado: False") + self.assertEqual(cerca_de_10(19), True, "Esperado: True") + self.assertEqual(cerca_de_10(31), True, "Esperado: True") + self.assertEqual(cerca_de_10(6), False, "Esperado: False") + self.assertEqual(cerca_de_10(10), True, "Esperado: True") + self.assertEqual(cerca_de_10(11), True, "Esperado: True") + self.assertEqual(cerca_de_10(21), True, "Esperado: True") + self.assertEqual(cerca_de_10(22), True, "Esperado: True") + self.assertEqual(cerca_de_10(23), False, "Esperado: False") + self.assertEqual(cerca_de_10(54), False, "Esperado: False") + self.assertEqual(cerca_de_10(155), False, "Esperado: False") + self.assertEqual(cerca_de_10(158), True, "Esperado: True") + self.assertEqual(cerca_de_10(3), False, "Esperado: False") + self.assertEqual(cerca_de_10(1), True, "Esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: q9_2 + :nocodelens: + + + Desarrolle una función llamada ``suma_loca`` que recibe tres números enteros ``a``, ``b`` y ``c``. La función debe devolver la suma de los tres números con la condición de que si algún número aparece repetido no será contado en la suma. |br| |br| + Ejemplos:|br| + ``suma_loca(1, 2, 3)`` -> ``6`` |br| + ``suma_loca(3, 2, 3)`` -> ``2`` |br| + ``suma_loca(3, 3, 3)`` -> ``0`` |br| + + ~~~~ + def suma_loca(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_loca(1, 2, 3), 6, "Esperado: 6") + self.assertEqual(suma_loca(3, 2, 3), 2, "Esperado: 2") + self.assertEqual(suma_loca(3, 3, 3), 0, "Esperado: 0") + self.assertEqual(suma_loca(9, 2, 2), 9, "Esperado: 9") + self.assertEqual(suma_loca(2, 2, 9), 9, "Esperado: 9") + self.assertEqual(suma_loca(2, 9, 2), 9, "Esperado: 9") + self.assertEqual(suma_loca(2, 9, 3), 14, "Esperado: 14") + self.assertEqual(suma_loca(4, 2, 3), 9, "Esperado: 9") + self.assertEqual(suma_loca(1, 3, 1), 3, "Esperado: 3") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: q9_3 + :nocodelens: + + + Desarrolle la función llamada ``suma_con_suerte`` que recibe tres números enteros ``a``, ``b`` y ``c``. La función debe devolver la suma de los tres números con la condición de que si uno de los números es el **13**, éste no cuenta en la suma así como todos los números que se encuentren a su derecha. |br| |br| + Ejemplos: |br| + ``suma_con_suerte(1, 2, 3)`` -> ``6`` |br| + ``suma_con_suerte(1, 2, 13)`` -> ``3`` |br| + ``suma_con_suerte(1, 13, 3)`` -> ``1`` |br| + + ~~~~ + def suma_con_suerte(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_con_suerte(1, 2, 3), 6, "Esperado: 6") + self.assertEqual(suma_con_suerte(1, 2, 13), 3, "Esperado: 3") + self.assertEqual(suma_con_suerte(1, 13, 3), 1, "Esperado: 1") + self.assertEqual(suma_con_suerte(1, 13, 13), 1, "Esperado: 1") + self.assertEqual(suma_con_suerte(6, 5, 2), 13, "Esperado: 13") + self.assertEqual(suma_con_suerte(13, 2, 3), 0, "Esperado: 0") + self.assertEqual(suma_con_suerte(13, 2, 13), 0, "Esperado: 0") + self.assertEqual(suma_con_suerte(13, 13, 2), 0, "Esperado: 0") + self.assertEqual(suma_con_suerte(9, 4, 13), 13, "Esperado: 13") + self.assertEqual(suma_con_suerte(8, 13, 2), 8, "Esperado: 8") + self.assertEqual(suma_con_suerte(7, 2, 1), 10, "Esperado: 10") + self.assertEqual(suma_con_suerte(3, 3, 13), 6, "Esperado: 6") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: q9_4 + :nocodelens: + + Desarrolle la función ``caracteres_dobles`` que recibe una cadena ``s`` y debe devolver los caracteres de la cadena original duplicados. |br| |br| + Ejemplos: |br| + ``caracteres_dobles('The')`` -> ``"TThhee"`` |br| + ``caracteres_dobles('AAbb')`` -> ``"AAAAbbbb"`` |br| + ``caracteres_dobles('Hi-There')`` -> ``"HHii--TThheerree"`` |br| + + ~~~~ + def caracteres_dobles(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(caracteres_dobles("The"), "TThhee", "Esperado: TThhee") + self.assertEqual(caracteres_dobles("AAbb"), "AAAAbbbb", "Esperado: AAAAbbbb") + self.assertEqual(caracteres_dobles("Hi-There"), "HHii--TThheerree", "Esperado: HHii--TThheerree") + self.assertEqual(caracteres_dobles("Word!"), "WWoorrdd!!", "Esperado: WWoorrdd!!") + self.assertEqual(caracteres_dobles("!!"), "!!!!", "Esperado: !!!!") + self.assertEqual(caracteres_dobles(""), "", "Esperado: ") + self.assertEqual(caracteres_dobles("a"), "aa", "Esperado: aa") + self.assertEqual(caracteres_dobles("."), "..", "Esperado: ..") + self.assertEqual(caracteres_dobles("aa"), "aaaa", "Esperado: aaaa") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: q9_5 + :nocodelens: + + Desarrolle la función, ``contar_saludo`` que recibe como parámetro una cadena ``s`` y devuelve el número de veces que aparece la cadena ``"hola"`` en ``s``. |br| |br| + Ejemplos: |br| + ``contar_saludo("abc hola ho")`` -> ``1`` |br| + ``contar_saludo("ABChola hola")`` -> ``2`` |br| + ``contar_saludo("holahola")`` -> ``2`` |br| + + ~~~~ + def contar_saludo(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(contar_saludo("abc hola ho"), 1, "Esperado: abc hola ho") + self.assertEqual(contar_saludo("ABChola hola"), 2, "Esperado: ABChi hola") + self.assertEqual(contar_saludo("holahola"), 2, "Esperado: holahola") + self.assertEqual(contar_saludo("holaHoLAhoLa"), 1, "Esperado: holaHOLAhoLa") + self.assertEqual(contar_saludo(""), 0, "Esperado: ") + self.assertEqual(contar_saludo("h"), 0, "Esperado: h") + self.assertEqual(contar_saludo("hola"), 1, "Esperado: hola") + self.assertEqual(contar_saludo("Hola is no HOLA on aHolA"), 0, "Esperado: Hola is no HOLA on aHolA") + self.assertEqual(contar_saludo("holaho not HOholaholA"), 2, "Esperado: holaho not HOholaholA") + + + myTests().main() + + + .. tab:: Ejercicio 6 + + .. activecode:: q9_6 + :nocodelens: + + Desarrolle la función ``gato_perro`` que recibe como parámetro una cadena ``s`` y devuelve ``True`` si en la cadena ``s`` aparece el mismo número de veces la cadena ``"gato"`` y la cadena ``"perro"`` o devuelve ``False`` en caso contrario. |br| |br| + Ejemplos: |br| + ``gato_perro("gatoperro")`` -> ``True`` |br| + ``gato_perro("gatogato")`` -> ``False`` |br| + ``gato_perro("1gato1cadoperro")`` -> ``True`` |br| + + ~~~~ + def gato_perro(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(gato_perro("gatoperro"), True, "Esperado: True") + self.assertEqual(gato_perro("gatogato"), False, "Esperado: False") + self.assertEqual(gato_perro("1gato1cadoperro"), True, "Esperado: True") + self.assertEqual(gato_perro("gatoxxperroxxxperro"), False, "Esperado: False") + self.assertEqual(gato_perro("gatoxperroxperroxgato"), True, "Esperado: True") + self.assertEqual(gato_perro("gatoxperroxperroxca"), False, "Esperado: False") + self.assertEqual(gato_perro("perroperrogato"), False, "Esperado: False") + self.assertEqual(gato_perro("perrooggato"), True, "Esperado: True") + self.assertEqual(gato_perro("perro"), False, "Esperado: False") + self.assertEqual(gato_perro("gato"), False, "Esperado: False") + self.assertEqual(gato_perro("ca"), True, "Esperado: True") + self.assertEqual(gato_perro("c"), True, "Esperado: True") + self.assertEqual(gato_perro(""), True, "Esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 7 + + .. activecode:: q9_7 + :nocodelens: + + Desarrolle la función ``contar_code`` que recibe como parámetro una cadena ``s`` y devuelve el número de veces que aparece la cadena ``"code"`` en ``s`` pero con la condición de que la letra ``'d'`` puede ser intercambiada por cualquier otra. Así, las cadenas ``"coze"`` y ``"coxe"`` deben ser contadas igualmente. |br| |br| + Ejemplos:|br| + ``contar_code("aaacodebbb")`` -> ``1`` |br| + ``contar_code("codexxcode")`` -> ``2`` |br| + ``contar_code("cozexxcope")`` -> ``2`` |br| + + ~~~~ + def contar_code(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(contar_code("aaacodebbb"), 1, "Esperado: 1") + self.assertEqual(contar_code("codexxcode"), 2, "Esperado: 2") + self.assertEqual(contar_code("cozexxcope"), 2, "Esperado: 2") + self.assertEqual(contar_code("cozfxxcope"), 1, "Esperado: 1") + self.assertEqual(contar_code("xxcozeyycop"), 1, "Esperado: 1") + self.assertEqual(contar_code("cozcop"), 0, "Esperado: 0") + self.assertEqual(contar_code("abcxyz"), 0, "Esperado: 0") + self.assertEqual(contar_code("code"), 1, "Esperado: 1") + self.assertEqual(contar_code("ode"), 0, "Esperado: 0") + self.assertEqual(contar_code("c"), 0, "Esperado: 0") + self.assertEqual(contar_code(""), 0, "Esperado: 0") + self.assertEqual(contar_code("AAcodeBBcoleCCccoreDD"), 3, "Esperado: 3") + self.assertEqual(contar_code("AAcodeBBcoleCCccorfDD"), 2, "Esperado: 2") + self.assertEqual(contar_code("coAcodeBcoleccoreDD"), 3, "Esperado: 3") + + + myTests().main() + + + .. tab:: Ejercicio 8 + + .. activecode:: q9_8 + :nocodelens: + + Sabiendo que la función ``lower()`` convierte los carácteres de una cadena en minúsculas. Desarrolle una función llamada ``finales_iguales`` que recibe dos cadenas ``a`` y ``b`` como parámetros. La función devolverá ``True`` si al final de la cadena ``a`` se encuentra la cadena ``b`` o si al final de la cadena ``b`` se encuentra la cadena ``a``. |br| |br| + Ejemplos: |br| + ``finales_iguales("Hiabc", "abc")`` -> ``True`` |br| + ``finales_iguales("AbC", "HiaBc")`` -> ``True`` |br| + ``finales_iguales("abc", "abXabc")`` -> ``True`` |br| + + ~~~~ + def finales_iguales(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(finales_iguales("Hiabc", "abc"), True, "Esperado: True") + self.assertEqual(finales_iguales("AbC", "HiaBc"), True, "Esperado: True") + self.assertEqual(finales_iguales("abc", "abXabc"), True, "Esperado: True") + self.assertEqual(finales_iguales("Hiabc", "abcd"), False, "Esperado: False") + self.assertEqual(finales_iguales("Hiabc", "bc"), True, "Esperado: True") + self.assertEqual(finales_iguales("Hiabcx", "bc"), False, "Esperado: False") + self.assertEqual(finales_iguales("abc", "abc"), True, "Esperado: True") + self.assertEqual(finales_iguales("xyz", "12xyz"), True, "Esperado: True") + self.assertEqual(finales_iguales("yz", "12xz"), False, "Esperado: False") + self.assertEqual(finales_iguales("Z", "12xz"), True, "Esperado: True") + self.assertEqual(finales_iguales("12", "12"), True, "Esperado: True") + self.assertEqual(finales_iguales("abcXYZ", "abcDEF"), False, "Esperado: False") + self.assertEqual(finales_iguales("ab", "ab12"), False, "Esperado: False") + self.assertEqual(finales_iguales("ab", "12ab"), True, "Esperado: True") + + + myTests().main() + + + .. tab:: Ejercicio 9 + + .. activecode:: q9_9 + :nocodelens: + + Desarrolle la función ``contar_pares`` que recibe una lista ``numeros`` de números enteros y devuelve la cantidad números pares que se encuentran en la lista. |br| |br| + Ejemplos: |br| + ``contar_pares([2, 1, 2, 3, 4])`` -> ``3`` |br| + ``contar_pares([2, 2, 0])`` -> ``3`` |br| + ``contar_pares([1, 3, 5])`` -> ``0`` |br| + + ~~~~ + def contar_pares(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(contar_pares([2, 1, 2, 3, 4]), 3, "Esperado: 3") + self.assertEqual(contar_pares([2, 2, 0]), 3, "Esperado: 3") + self.assertEqual(contar_pares([1, 3, 5]), 0, "Esperado: 0") + self.assertEqual(contar_pares([]), 0, "Esperado: 0") + self.assertEqual(contar_pares([11, 9, 0, 1]), 1, "Esperado: 1") + self.assertEqual(contar_pares([2, 11, 9, 0]), 2, "Esperado: 2") + self.assertEqual(contar_pares([2]), 1, "Esperado: 1") + self.assertEqual(contar_pares([2, 5, 12]), 2, "Esperado: 2") + + + myTests().main() + + + .. tab:: Ejercicio 10 + + .. activecode:: q9_10 + :nocodelens: + + Desarrolle la función ``suma_con_mas_suerte`` que recibe una lista ``numeros`` de números enteros y devuelve la suma de los números de la lista con la condición de que si uno de los números es el **13**, éste no cuenta en la suma así como todos los números que se encuentren a su derecha. |br| |br| + Ejemplos: |br| + ``suma_con_mas_suerte([1, 2, 2, 1])`` -> ``6`` |br| + ``suma_con_mas_suerte([1, 1])`` -> ``2`` |br| + ``suma_con_mas_suerte([1, 2, 13, 1, 13])`` -> ``3`` |br| + ``suma_con_mas_suerte([13, 1, 2, 3, 4])`` -> ``0`` |br| + + ~~~~ + def suma_con_mas_suerte(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_con_mas_suerte([1, 2, 2, 1]), 6, "Esperado: 6") + self.assertEqual(suma_con_mas_suerte([1, 1]), 2, "Esperado: 2") + self.assertEqual(suma_con_mas_suerte([1, 2, 2, 1, 13]), 6, "Esperado: 6") + self.assertEqual(suma_con_mas_suerte([1, 2, 13, 2, 1, 13]), 3, "Esperado: 3") + self.assertEqual(suma_con_mas_suerte([13, 1, 2, 13, 2, 1, 13]), 0, "Esperado: 0") + self.assertEqual(suma_con_mas_suerte([0, 1, 2, 13, 2, 1, 13]), 3, "Esperado: 3") + self.assertEqual(suma_con_mas_suerte([]), 0, "Esperado: 0") + self.assertEqual(suma_con_mas_suerte([13]), 0, "Esperado: 0") + self.assertEqual(suma_con_mas_suerte([0, 5, 1, 2, 13, 100]), 8, "Esperado: 8") + self.assertEqual(suma_con_mas_suerte([13, 13]), 0, "Esperado: 0") + self.assertEqual(suma_con_mas_suerte([13, 0, 13]), 0, "Esperado: 0") + self.assertEqual(suma_con_mas_suerte([13, 1, 13]), 0, "Esperado: 0") + self.assertEqual(suma_con_mas_suerte([5, 7, 2]), 14, "Esperado: 14") + self.assertEqual(suma_con_mas_suerte([5, 13, 2]), 5, "Esperado: 5") + self.assertEqual(suma_con_mas_suerte([0]), 0, "Esperado: 0") + self.assertEqual(suma_con_mas_suerte([13, 0]), 0, "Esperado: 0") + + + myTests().main() + + + .. tab:: Ejercicio 11 + + .. activecode:: q9_11 + :nocodelens: + + Desarrolle la función ``tiene_2`` que recibe como parámetro una lista ``numeros`` de números enteros y devuelve ``True`` si en la lista aparecen dos números iguales consecutivos y ``False`` en caso contrario. |br| |br| + Ejemplos: |br| + ``tiene_2([1, 2, 2])`` -> ``True`` |br| + ``tiene_2([1, 2, 1, 2])`` -> ``False`` |br| + ``tiene_2([2, 1, 2])`` -> ``False`` |br| + + ~~~~ + def tiene_2(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(tiene_2([1, 2, 2]), True, "Esperado: True") + self.assertEqual(tiene_2([1, 2, 1, 2]), False, "Esperado: False") + self.assertEqual(tiene_2([2, 1, 2]), False, "Esperado: False") + self.assertEqual(tiene_2([2, 2, 1, 2]), True, "Esperado: True") + self.assertEqual(tiene_2([1, 3, 2]), False, "Esperado: False") + self.assertEqual(tiene_2([1, 3, 2, 2]), True, "Esperado: True") + self.assertEqual(tiene_2([2, 3, 2, 2]), True, "Esperado: True") + self.assertEqual(tiene_2([4, 2, 4, 2, 2, 5]), True, "Esperado: True") + self.assertEqual(tiene_2([1, 2]), False, "Esperado: False") + self.assertEqual(tiene_2([2, 2]), True, "Esperado: True") + self.assertEqual(tiene_2([2]), False, "Esperado: False") + self.assertEqual(tiene_2([]), False, "Esperado: False") + self.assertEqual(tiene_2([3, 3, 2, 2]), True, "Esperado: True") + self.assertEqual(tiene_2([5, 2, 5, 2]), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 12 + + .. activecode:: q9_12 + :nocodelens: + + Desarrolle la función ``suma_en_lista`` que recibe dos parámetros, un entero ``n`` y un lista ``numeros`` de números. La función debe devolver ``True`` si existen dos elementos distintos de la lista que su suma da como resultado ``n`` y devolver ``False`` en caso contrario. |br| |br| + Ejemplos: |br| + ``suma_en_lista(5, [1, 2, 3, 4])`` -> ``True`` |br| + ``suma_en_lista(9, [1, 2, 3, 4])`` -> ``False`` |br| + ``suma_en_lista(0, [1, 2, 3, 4])`` -> ``False`` |br| + ``suma_en_lista(8, [1, 2, 3, 4])`` -> ``False`` |br| + ``suma_en_lista(4, [2, 2, 2, 2])`` -> ``False`` |br| + ``suma_en_lista(4, [2, 2, 1, 3])`` -> ``True`` |br| + + ~~~~ + def suma_en_lista(n, numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_en_lista(5, [1, 2, 3, 4]), True, "Esperado: True") + self.assertEqual(suma_en_lista(9, [1, 2, 3, 4]), False, "Esperado: False") + self.assertEqual(suma_en_lista(0, [1, 2, 3, 4]), False, "Esperado: False") + self.assertEqual(suma_en_lista(8, [1, 2, 3, 4]), False, "Esperado: False") + self.assertEqual(suma_en_lista(4, [2, 2, 2, 2]), False, "Esperado: False") + self.assertEqual(suma_en_lista(4, [2, 2, 1, 3]), True, "Esperado: True") + self.assertEqual(suma_en_lista(42, [40, 2, 3, 39]), True, "Esperado: True") + self.assertEqual(suma_en_lista(10, [5, 5, 4, 6]), True, "Esperado: True") + self.assertEqual(suma_en_lista(8, [5, 5, 4, 4]), False, "Esperado: False") + + + myTests().main() + + + .. tab:: Ejercicio 13 + + .. activecode:: q9_13 + :nocodelens: + + En una construcción se desea construir una fila de ladrillos. Se tienen ladrillos pequeños y ladrillos grandes. Los ladrillos pequeños son de 1 unidad de longitud mientras que los ladrillos grandes son de 5 unidades de longitud. Desarrolle la función ``construir_fila`` que recibe tres parámetros, ``n_lad_peq``, ``n_lad_grand`` y ``longitud_fila``. Estos parámetros son números enteros que representan la cantidad de ladrillos pequeños, cantidad de ladrillos grandes y la longitud de la fila que se quiere construir, respectivamente. La función debe devolver ``True`` si es posible armar la fila, o ``False`` en caso contrario. |br| |br| + Ejemplos: |br| + ``construir_fila(3, 1, 8)`` -> ``True`` |br| + *Explicación*: Para construir una longitud de 8 metros, se usarían 1 ladrillo grande y 3 ladrillos pequeños |br| + *Por lo tanto*: 1 + 1 + 1 + 5 = 8 |br| + + ``construir_fila(3, 1, 9)`` -> ``False`` |br| + *Explicación*: Para construir una longitud de 9 metros no se podría porque solamente se tienen 3 ladrillos pequeños (de 1 metro de longitud) y 1 ladrillo grande (de 5 metros de longitud). |br| + *Por lo tanto*: 1 + 1 + 1 + 5 < 9 en este caso se necesitaría 1 ladrillo grande y 4 pequeños. |br| + + ``construir_fila(3, 2, 10)`` -> ``True`` |br| + *Explicación*: Para llenar una longitud de 10 metros, se usarían solamente los 2 ladrillos grandes disponibles. |br| + *Por lo tanto*: 5 + 5 = 10 |br| + + ~~~~ + def construir_fila(n_lad_peq, n_lad_grand, longitud_fila): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(construir_fila(3, 1, 8), True, "Esperado: True") + self.assertEqual(construir_fila(3, 1, 9), False, "Esperado: False") + self.assertEqual(construir_fila(3, 2, 10), True, "Esperado: True") + self.assertEqual(construir_fila(3, 2, 8), True, "Esperado: True") + self.assertEqual(construir_fila(3, 2, 9), False, "Esperado: False") + self.assertEqual(construir_fila(6, 1, 11), True, "Esperado: True") + self.assertEqual(construir_fila(6, 0, 11), False, "Esperado: False") + self.assertEqual(construir_fila(3, 1, 7), True, "Esperado: True") + self.assertEqual(construir_fila(1, 1, 7), False, "Esperado: False") + self.assertEqual(construir_fila(2, 1, 7), True, "Esperado: True") + self.assertEqual(construir_fila(7, 1, 11), True, "Esperado: True") + self.assertEqual(construir_fila(7, 1, 8), True, "Esperado: True") + self.assertEqual(construir_fila(7, 1, 13), False, "Esperado: False") + self.assertEqual(construir_fila(43, 1, 46), True, "Esperado: True") + self.assertEqual(construir_fila(40, 1, 46), False, "Esperado: False") + self.assertEqual(construir_fila(22, 2, 33), False, "Esperado: False") + self.assertEqual(construir_fila(0, 2, 10), True, "Esperado: True") + self.assertEqual(construir_fila(1000000, 1000, 1000100), True, "Esperado: True") + self.assertEqual(construir_fila(2, 1000000, 100003), False, "Esperado: False") + self.assertEqual(construir_fila(12, 2, 21), True, "Esperado: True") + + + myTests().main() diff --git a/293/_sources/quiz/Quiz9_en.rst.txt b/293/_sources/quiz/Quiz9_en.rst.txt new file mode 100644 index 0000000000..09d05e212f --- /dev/null +++ b/293/_sources/quiz/Quiz9_en.rst.txt @@ -0,0 +1,517 @@ +======== +Quiz - 9 +======== + +.. |br| raw:: html + +
+ + +.. tabbed:: quiz9 + + .. tab:: Exercise 1 + + .. activecode:: q9_1_en + :nocodelens: + + Develop the function ``near_ten`` that receives an integer ``n`` and returns ``True`` when ``n`` is a multiple of 10, or when ``n`` is one or two units away from it. Otherwise, return ``False``. |br| |br| + Examples: |br| + ``near_ten(12)`` -> ``True`` |br| + ``near_ten(17)`` -> ``False`` |br| + ``near_ten(19)`` -> ``True`` |br| + + ~~~~ + def near_ten(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(near_ten(12), True, "Expected: True") + self.assertEqual(near_ten(17), False, "Expected: False") + self.assertEqual(near_ten(19), True, "Expected: True") + self.assertEqual(near_ten(31), True, "Expected: True") + self.assertEqual(near_ten(6), False, "Expected: False") + self.assertEqual(near_ten(10), True, "Expected: True") + self.assertEqual(near_ten(11), True, "Expected: True") + self.assertEqual(near_ten(21), True, "Expected: True") + self.assertEqual(near_ten(22), True, "Expected: True") + self.assertEqual(near_ten(23), False, "Expected: False") + self.assertEqual(near_ten(54), False, "Expected: False") + self.assertEqual(near_ten(155), False, "Expected: False") + self.assertEqual(near_ten(158), True, "Expected: True") + self.assertEqual(near_ten(3), False, "Expected: False") + self.assertEqual(near_ten(1), True, "Expected: True") + + + myTests().main() + + .. tab:: Exercise 2 + + .. activecode:: q9_2_en + :nocodelens: + + Develop a function called "suma_loca" that receives three integers "a", "b", and "c". The function must return the sum of the three numbers with the condition that if any number appears twice, it will not be counted in the sum. |br| |br| + Examples: |br| + ``suma_loca(1, 2, 3)`` -> ``6`` |br| + ``suma_loca(3, 2, 3)`` -> ``2`` |br| + ``suma_loca(3, 3, 3)`` -> ``0`` |br| + + ~~~~ + def suma_loca(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_loca(1, 2, 3), 6, "Expected: 6") + self.assertEqual(suma_loca(3, 2, 3), 2, "Expected: 2") + self.assertEqual(suma_loca(3, 3, 3), 0, "Expected: 0") + self.assertEqual(suma_loca(9, 2, 2), 9, "Expected: 9") + self.assertEqual(suma_loca(2, 2, 9), 9, "Expected: 9") + self.assertEqual(suma_loca(2, 9, 2), 9, "Expected: 9") + self.assertEqual(suma_loca(2, 9, 3), 14, "Expected: 14") + self.assertEqual(suma_loca(4, 2, 3), 9, "Expected: 9") + self.assertEqual(suma_loca(1, 3, 1), 3, "Expected: 3") + + myTests().main() + + .. tab:: Exercise 3 + + .. activecode:: q9_3_en + :nocodelens: + + Develop the function called "suma_con_suerte" that receives three integers "a", "b", and "c". The function must return the sum of the three numbers with the condition that if one of the numbers is **13**, it won't count in the sum, as well as all the numbers to its right. |br| |br| + Examples: |br| + ``suma_con_suerte(1, 2, 3)`` -> ``6`` |br| + ``suma_con_suerte(1, 2, 13)`` -> ``3`` |br| + ``suma_con_suerte(1, 13, 3)`` -> ``1`` |br| + + ~~~~ + def suma_con_suerte(a, b, c): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_con_suerte(1, 2, 3), 6, "Expected: 6") + self.assertEqual(suma_con_suerte(1, 2, 13), 3, "Expected: 3") + self.assertEqual(suma_con_suerte(1, 13, 3), 1, "Expected: 1") + self.assertEqual(suma_con_suerte(1, 13, 13), 1, "Expected: 1") + self.assertEqual(suma_con_suerte(6, 5, 2), 13, "Expected: 13") + self.assertEqual(suma_con_suerte(13, 2, 3), 0, "Expected: 0") + self.assertEqual(suma_con_suerte(13, 2, 13), 0, "Expected: 0") + self.assertEqual(suma_con_suerte(13, 13, 2), 0, "Expected: 0") + self.assertEqual(suma_con_suerte(9, 4, 13), 13, "Expected: 13") + self.assertEqual(suma_con_suerte(8, 13, 2), 8, "Expected: 8") + self.assertEqual(suma_con_suerte(7, 2, 1), 10, "Expected: 10") + self.assertEqual(suma_con_suerte(3, 3, 13), 6, "Expected: 6") + + myTests().main() + + .. tab:: Exercise 4 + + .. activecode:: q9_4_en + :nocodelens: + + Develop the function called "caracteres_dobles" that receives a string "s" and should return the original string duplicated. |br| |br| + Examples: |br| + ``caracteres_dobles('The')`` -> ``"TThhee"`` |br| + ``caracteres_dobles('AAbb')`` -> ``"AAAAbbbb"`` |br| + ``caracteres_dobles('Hi-There')`` -> ``"HHii--TThheerree"`` |br| + + ~~~~ + def caracteres_dobles(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(caracteres_dobles("The"), "TThhee", "Expected: TThhee") + self.assertEqual(caracteres_dobles("AAbb"), "AAAAbbbb", "Expected: AAAAbbbb") + self.assertEqual(caracteres_dobles("Hi-There"), "HHii--TThheerree", "Expected: HHii--TThheerree") + self.assertEqual(caracteres_dobles("Word!"), "WWoorrdd!!", "Expected: WWoorrdd!!") + self.assertEqual(caracteres_dobles("!!"), "!!!!", "Expected: !!!!") + self.assertEqual(caracteres_dobles(""), "", "Expected: ") + self.assertEqual(caracteres_dobles("a"), "aa", "Expected: aa") + self.assertEqual(caracteres_dobles("."), "..", "Expected: ..") + self.assertEqual(caracteres_dobles("aa"), "aaaa", "Expected: aaaa") + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: q9_5_en + :nocodelens: + + Develop the function ``count_greeting`` which receives a string ``s`` as a parameter and returns the number of times the string ``"hello"`` appears in ``s``. |br| |br| + Examples: |br| + ``count_greeting ("abc hello ho")`` -> ``1`` |br| + ``count_greeting ("ABChello hello")`` -> ``2`` |br| + ``count_greeting ("hellohello")`` -> ``2`` |br| + + ~~~~ + def count_greeting(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(count_greeting("abc hello ho"), 1, "Expected: abc hello ho") + self.assertEqual(count_greeting("ABChello hello"), 2, "Expected: ABCh i hello") + self.assertEqual(count_greeting("hellohello"), 2, "Expected: hellohello") + self.assertEqual(count_greeting("helloHoLAhoLa"), 1, "Expected: helloHOLAhoLa") + self.assertEqual(count_greeting(""), 0, "Expected: ") + self.assertEqual(count_greeting("h"), 0, "Expected: h") + self.assertEqual(count_greeting("hello"), 1, "Expected: hello") + self.assertEqual(count_greeting("Hello is no HOLA on aHolA"),0, "Expected: Hello is no HOLA on aHolA") + self.assertEqual(count_greeting("helloh not HOholaholA"), 2, "Expected: helloh not HOholaholA") + + + myTests().main() + + + .. tab:: Exercise 6 + + .. activecode:: q9_6_en + :nocodelens: + + Develop the function ``cat_dog`` which receives a string ``s`` as a parameter and returns ``True`` if the string ``"cat"`` and the string ``"dog"`` appear the same number of times in the string ``s`` or returns ``False`` otherwise. | br | | br | + Examples: |br| + ``cat_dog ("catdog")`` -> ``True`` |br| + ``cat_dog ("catcat")`` -> ``False`` |br| + ``cat_dog ("1cat1dog")`` -> ``True`` |br| + + ~~~~ + def cat_dog(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(cat_dog("catdog"), True, "Expected: True") + self.assertEqual(cat_dog("catcat"), False, "Expected: False") + self.assertEqual(cat_dog("1cat1cadoperro"), True, "Expected: True") + self.assertEqual(cat_dog("catxxperroxxxperro"), False, "Expected: False") + self.assertEqual(cat_dog("catxperroxperroxcadogcat"), True, "Expected: True") + self.assertEqual(cat_dog("catxperroxperroxca"), False, "Expected: False") + self.assertEqual(cat_dog("perroperrocat"), False, "Expected: False") + self.assertEqual(cat_dog("perroogcat"), True, "Expected: True") + self.assertEqual(cat_dog("perro"), False, "Expected: False") + self.assertEqual(cat_dog("cat"), False, "Expected: False") + self.assertEqual(cat_dog("ca"), True, "Expected: True") + self.assertEqual(cat_dog("c"), True, "Expected: True") + self.assertEqual(cat_dog(""), True, "Expected: True") + + + myTests().main() + + + .. tab:: Exercise 7 + + .. activecode:: q9_7_en + :nocodelens: + + Develop the function ``count_code`` which receives a string ``s`` as a parameter and returns the number of times the string ``"code"`` appears in ``s``, but with the condition that the letter ``'d'`` can be exchanged for any other letter. Thus, the strings ``"coze"`` and ``"coze"`` should be counted equally. |br| |br| + Examples:|br| + ``count_code("aaacodebbb")`` -> ``1`` |br| + ``count_code("codexxcode")`` -> ``2`` |br| + ``count_code("cozexxcope")`` -> ``2`` |br| + + ~~~~ + def count_code(s): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(count_code("aaacodebbb"), 1, "Expected: 1") + self.assertEqual(count_code("codexxcode"), 2, "Expected: 2") + self.assertEqual(count_code("cozexxcope"), 2, "Expected: 2") + self.assertEqual(count_code("cozfxxcope"), 1, "Expected: 1") + self.assertEqual(count_code("xxcozeyycop"), 1, "Expected: 1") + self.assertEqual(count_code("cozcop"), 0, "Expected: 0") + self.assertEqual(count_code("abcxyz"), 0, "Expected: 0") + self.assertEqual(count_code("code"), 1, "Expected: 1") + self.assertEqual(count_code("ode"), 0, "Expected: 0") + self.assertEqual(count_code("c"), 0, "Expected: 0") + self.assertEqual(count_code(""), 0, "Expected: 0") + self.assertEqual(count_code("AAcodeBBcoleCCccoreDD"), 3, "Expected: 3") + self.assertEqual(count_code("AAcodeBBcoleCCccorfDD"), 2, "Expected: 2") + self.assertEqual(count_code("coAcodeBcoleccoreDD"), 3, "Expected: 3") + + + myTests().main() + + + .. tab:: Exercise 8 + + .. activecode:: q9_8_en + :nocodelens: + + Knowing that the function ``lower()`` converts the characters of a string to lowercase. Develop a function called ``end_equals`` that receives two strings ``a`` and ``b`` as parameters. The function will return ``True`` if the string ``b`` is found at the end of string ``a`` or if the string ``a`` is found at the end of string ``b``. |br| |br| + Examples: |br| + ``end_equals("Hiabc", "abc")`` -> ``True`` |br| + ``end_equals("AbC", "HiaBc")`` -> ``True`` |br| + ``end_equals("abc", "abXabc")`` -> ``True`` |br| + + ~~~~ + def end_equals(a, b): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(end_equals("Hiabc", "abc"), True, "Expected: True") + self.assertEqual(end_equals("AbC", "HiaBc"), True, "Expected: True") + self.assertEqual(end_equals("abc", "abXabc"), True, "Expected: True") + self.assertEqual(end_equals("Hiabc", "abcd"), False, "Expected: False") + self.assertEqual(end_equals("Hiabc", "bc"), True, "Expected: True") + self.assertEqual(end_equals("Hiabcx", "bc"), False, "Expected: False") + self.assertEqual(end_equals("abc", "abc"), True, "Expected: True") + self.assertEqual(end_equals("xyz", "12xyz"), True, "Expected: True") + self.assertEqual(end_equals("yz", "12xz"), False, "Expected: False") + self.assertEqual(end_equals("Z", "12xz"), True, "Expected: True") + self.assertEqual(end_equals("12", "12"), True, "Expected: True") + self.assertEqual(end_equals("abcXYZ", "abcDEF"), False, "Expected: False") + self.assertEqual(end_equals("ab", "ab12"), False, "Expected: False") + self.assertEqual(end_equals("ab", "12ab"), True, "Expected: True") + + + myTests().main() + + .. tab:: Exercise 9 + + .. activecode:: q9_9_en + :nocodelens: + + Develop the function ``count_pairs`` that receives a list ``numbers`` of integers and returns the number of even numbers in the list. |br| |br| + Examples: |br| + ``count_pairs([2, 1, 2, 3, 4])`` -> ``3`` |br| + ``count_pairs([2, 2, 0])`` -> ``3`` |br| + ``count_pairs([1, 3, 5])`` -> ``0`` |br| + + ~~~~ + def count_pairs(numbers): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(count_pairs([2, 1, 2, 3, 4]), 3, "Expected: 3") + self.assertEqual(count_pairs([2, 2, 0]), 3, "Expected: 3") + self.assertEqual(count_pairs([1, 3, 5]), 0, "Expected: 0") + self.assertEqual(count_pairs([]), 0, "Expected: 0") + self.assertEqual(count_pairs([11, 9, 0, 1]), 1, "Expected: 1") + self.assertEqual(count_pairs([2, 11, 9, 0]), 2, "Expected: 2") + self.assertEqual(count_pairs([2]), 1, "Expected: 1") + self.assertEqual(count_pairs([2, 5, 12]), 2, "Expected: 2") + + + myTests().main() + + + + .. tab:: Exercise 10 + + .. activecode:: q9_10_en + :nocodelens: + + Develop the function `` suma_con_mas_suerte '' that receives a list `` numbers '' of integers and returns the sum of the numbers in the list with the condition that if one of the numbers is ** 13 ** , this is not counted in the sum as well as all numbers that are to its right. | br | | br | + Examples: | br | + `` suma_con_mas_suerte ([1, 2, 2, 1]) '' -> `` 6 '' | br | + `` suma_con_mas_suerte ([1, 1]) '' -> `` 2 '' | br | + `` suma_con_mas_suerte ([1, 2, 13, 1, 13]) '' -> `` 3 '' | br | + `` suma_con_mas_suerte ([13, 1, 2, 3, 4]) '' -> `` 0 '' | br | + + ~~~~ + def suma_con_mas_suerte (numbers): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests (TestCaseGui): + def testOne (self): + self.assertEqual (suma_con_mas_suerte ([1, 2, 2, 1]), 6, "Expected: 6") + self.assertEqual (suma_con_mas_suerte ([1, 1]), 2, "Expected: 2") + self.assertEqual (suma_con_mas_suerte ([1, 2, 13, 1, 13]), 6, "Expected: 6") + self.assertEqual (suma_con_mas_suerte ([1, 2, 13, 2, 1, 13]), 3, "Expected: 3") + self.assertEqual (suma_con_mas_suerte ([13, 1, 2, 13, 2, 1, 13]), 0, "Expected: 0") + self.assertEqual (suma_con_mas_suerte ([0, 1, 2, 13, 2, 1, 13]), 3, "Expected: 3") + self.assertEqual (suma_con_mas_suerte ([]), 0, "Expected: 0") + self.assertEqual (suma_con_mas_suerte ([13]), 0, "Expected: 0") + self.assertEqual (suma_con_mas_suerte ([0, 5, 1, 2, 13, 100]), 8, "Expected: 8") + self.assertEqual (suma_con_mas_suerte ([13, 13]), 0, "Expected: 0") + self.assertEqual (suma_con_mas_suerte ([13, 0, 13]), 0, "Expected: 0") + self.assertEqual (suma_con_mas_suerte ([13, 1, 13]), 0, "Expected: 0") + self.assertEqual (suma_con_mas_suerte ([5, 7, 2]), 14, "Expected: 14") + self.assertEqual (suma_con_mas_suerte ([5, 13, 2]), 5, "Expected: 5") + self.assertEqual (suma_con_mas_suerte ([0]), 0, "Expected: 0") + self.assertEqual (suma_con_mas_suerte ([13, 0]), 0, "Expected: 0") + + + myTests (). main () + + + + .. tab:: Exercise 11 + + .. activecode:: q9_11_en + :nocodelens: + + Develop the function ``tiene_2`` that receives a list ``numeros`` of integers as parameter and returns ``True`` if there are two consecutive equal numbers in the list, and ``False`` otherwise. |br| |br| + Examples: |br| + ``tiene_2([1, 2, 2])`` -> ``True`` |br| + ``tiene_2([1, 2, 1, 2])`` -> ``False`` |br| + ``tiene_2([2, 1, 2])`` -> ``False`` |br| + + ~~~~ + def tiene_2(numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(tiene_2([1, 2, 2]), True, "Expected: True") + self.assertEqual(tiene_2([1, 2, 1, 2]), False, "Expected: False") + self.assertEqual(tiene_2([2, 1, 2]), False, "Expected: False") + self.assertEqual(tiene_2([2, 2, 1, 2]), True, "Expected: True") + self.assertEqual(tiene_2([1, 3, 2]), False, "Expected: False") + self.assertEqual(tiene_2([1, 3, 2, 2]), True, "Expected: True") + self.assertEqual(tiene_2([2, 3, 2, 2]), True, "Expected: True") + self.assertEqual(tiene_2([4, 2, 4, 2, 2, 5]), True, "Expected: True") + self.assertEqual(tiene_2([1, 2]), False, "Expected: False") + self.assertEqual(tiene_2([2, 2]), True, "Expected: True") + self.assertEqual(tiene_2([2]), False, "Expected: False") + self.assertEqual(tiene_2([]), False, "Expected: False") + self.assertEqual(tiene_2([3, 3, 2, 2]), True, "Expected: True") + self.assertEqual(tiene_2([5, 2, 5, 2]), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 12 + + .. activecode:: q9_12_en + :nocodelens: + + Develop the function ``suma_en_lista`` that receives two parameters, an integer ``n`` and a list ``numeros`` of numbers. The function should return ``True`` if there are two different elements in the list whose sum is ``n``, and ``False`` otherwise. |br| |br| + Examples: |br| + ``suma_en_lista(5, [1, 2, 3, 4])`` -> ``True`` |br| + ``suma_en_lista(9, [1, 2, 3, 4])`` -> ``False`` |br| + ``suma_en_lista(0, [1, 2, 3, 4])`` -> ``False`` |br| + ``suma_en_lista(8, [1, 2, 3, 4])`` -> ``False`` |br| + ``suma_en_lista(4, [2, 2, 2, 2])`` -> ``False`` |br| + ``suma_en_lista(4, [2, 2, 1, 3])`` -> ``True`` |br| + + ~~~~ + def suma_en_lista(n, numeros): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(suma_en_lista(5, [1, 2, 3, 4]), True, "Expected: True") + self.assertEqual(suma_en_lista(9, [1, 2, 3, 4]), False, "Expected: False") + self.assertEqual(suma_en_lista(0, [1, 2, 3, 4]), False, "Expected: False") + self.assertEqual(suma_en_lista(8, [1, 2, 3, 4]), False, "Expected: False") + self.assertEqual(suma_en_lista(4, [2, 2, 2, 2]), False, "Expected: False") + self.assertEqual(suma_en_lista(4, [2, 2, 1, 3]), True, "Expected: True") + self.assertEqual(suma_en_lista(42, [40, 2, 3, 39]), True, "Expected: True") + self.assertEqual(suma_en_lista(10, [5, 5, 4, 6]), True, "Expected: True") + self.assertEqual(suma_en_lista(8, [5, 5, 4, 4]), False, "Expected: False") + + + myTests().main() + + + .. tab:: Exercise 13 + + .. activecode:: q9_13_en + :nocodelens: + + In a construction it is desired to build a row of bricks. There are small bricks and large bricks. Small bricks are 1 unit in length while large bricks are 5 units in length. Develop the function ``build_row`` which receives three parameters, ``num_small_bricks``, ``num_large_bricks``, and ``row_length``. These parameters are integer numbers that represent the quantity of small bricks, quantity of large bricks, and the length of the row you want to build, respectively. The function must return ``True`` if it is possible to build the row, or ``False`` otherwise. |br| |br| + Examples: |br| + ``build_row(3, 1, 8)`` -> ``True`` |br| + *Explanation*: To build a length of 8 meters, 1 large brick and 3 small bricks would be used. |br| + *Therefore*: 1 + 1 + 1 + 5 = 8 |br| + + ``build_row(3, 1, 9)`` -> ``False`` |br| + *Explanation*: To build a length of 9 meters it wouldn't be possible because there are only 3 small bricks (1 meter in length) and 1 large brick (5 meters in length). |br| + *Therefore*: 1 + 1 + 1 + 5 < 9 in this case 1 large brick and 4 small bricks would be needed. |br| + + ``build_row(3, 2, 10)`` -> ``True`` |br| + *Explanation*: To fill a length of 10 meters, only the 2 available large bricks would be used. |br| + *Therefore*: 5 + 5 = 10 |br| + + ~~~~ + def build_row(num_small_bricks, num_large_bricks, row_length): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + self.assertEqual(build_row(3, 1, 8), True, "Expected: True") + self.assertEqual(build_row(3, 1, 9), False, "Expected: False") + self.assertEqual(build_row(3, 2, 10), True, "Expected: True") + self.assertEqual(build_row(3, 2, 8), True, "Expected: True") + self.assertEqual(build_row(3, 2, 9), False, "Expected: False") + self.assertEqual(build_row(6, 1, 11), True, "Expected: True") + self.assertEqual(build_row(6, 0, 11), False, "Expected: False") + self.assertEqual(build_row(3, 1, 7), True, "Expected: True") + self.assertEqual(build_row(1, 1, 7), False, "Expected: False") + self.assertEqual(build_row(2, 1, 7), True, "Expected: True") + self.assertEqual(build_row(7, 1, 11), True, "Expected: True") + self.assertEqual(build_row(7, 1, 8), True, "Expected: True") + self.assertEqual(build_row(7, 1, 13), False, "Expected: False") + self.assertEqual(build_row(43, 1, 46), True, "Expected: True") + self.assertEqual(build_row(40, 1, 46), False, "Expected: False") + self.assertEqual(build_row(22, 2, 33), False, "Expected: False") + self.assertEqual(build_row(0, 2, 10), True, "Expected: True") + self.assertEqual(build_row(1000000, 1000, 1000100), True, "Expected: True") + self.assertEqual(build_row(2, 1000000, 100003), False, "Expected: False") + self.assertEqual(build_row(12, 2, 21), True, "Expected: True") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/QuizExtras.rst.txt b/293/_sources/quiz/QuizExtras.rst.txt new file mode 100644 index 0000000000..27c0bc1229 --- /dev/null +++ b/293/_sources/quiz/QuizExtras.rst.txt @@ -0,0 +1,175 @@ +============= +Quiz - Extras +============= + +.. |br| raw:: html + +
+ + +.. tabbed:: quizExtras + + .. tab:: Ejercicio 1 + + .. activecode:: qExtra_1 + :nocodelens: + + **Problema de Josephus**. Imagine que tenemos ``n`` personas dispuestas en un círculo. Suponga que esas personas están numeradas de 1 a ``n`` en sentido horario. + Comenzando con la persona número **1**, ejecute el círculo en sentido horario y elimine cada ``m``-ésima persona, siempre y cuando el círculo + tenga dos o más personas. El reto es desarrollar la función ``josephus`` que toma a ``n`` y a ``m`` como parámetros, ambos números enteros positivos. + La función debe devolver el número de la persona en el círculo que sobrevivió. |br| |br| + + ~~~~ + def josephus(n, m): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(josephus(50, 3), 11, "Esperado: 11") + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: qExtra_2 + :nocodelens: + + Implemente el algoritmo de la **Criba de Eratóstenes**. |br| + `Criba de Eratóstenes `_ |br| + El reto es desarrollar la función ``criba_de_Eratostenes`` que toma a ``n``, un número entero positivo, como parámetro + y devuelve la cantidad de números primos que hay en el intervalo **[2, n]**. Utilice la Criba de Eratóstenes para resolver + este problema. |br| |br| + Ejemplos: |br| + ``criba_de_Eratostenes(20)`` -> ``8`` |br| + ``criba_de_Eratostenes(12)`` -> ``5`` |br| + + ~~~~ + def criba_de_Eratostenes(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(criba_de_Eratostenes(20), 8, "Esperado: 8") + self.assertEqual(criba_de_Eratostenes(12), 5, "Esperado: 5") + self.assertEqual(criba_de_Eratostenes(30), 10, "Esperado: 10") + self.assertEqual(criba_de_Eratostenes(5), 3, "Esperado: 3") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: qExtra_3 + :nocodelens: + + **Problema 2 del Proyecto Euler**. `Problema `_ |br| + Primero, verifique para que sirve la palabra clave ``yield`` en Python. Después, resuelva la adaptación del problema 2 del *Proyecto Euler* + que está a continuación: |br| + Desarrolle la función ``p_euler`` que toma a ``n``, un entero positivo, como argumento, y devuelva la suma de todos los números pares menores a ``n`` + dentro de la secuencia Fibonacci de ``n``. |br| |br| + Ejemplo: |br| + ``p_euler(10)`` -> ``10`` |br| + **Explicación**: los diez primero términos de la secuencia Fibonacci son:: + + 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 + + Por ende, los números pares dentro de esta secuencia son:: + + 2, 8, 34 + + Sin embargo, solo ``2`` y ``8`` cumplen con ser menores que ``n`` (en este caso menores que 10). La suma de éstos es ``10``. + + ~~~~ + def p_euler(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(p_euler(4000000), 4613732, "Esperado: 4613732") + self.assertEqual(p_euler(10), 10, "Esperado: 10") + self.assertEqual(p_euler(100), 44, "Esperado: 44") + + + myTests().main() + + + .. tab:: Ejercicio 4 + + .. activecode:: qExtra_4 + :nocodelens: + + En el libro “El Hombre que Calculaba”, de *Malba Tahan*, un personaje quería ganar los granos de trigo que estaban distribuidos sobre un tablero de ajedrez del siguiente modo: + un grano en la primera casilla del tablero, el doble (2) en la segunda, nuevamente el doble (4) en la tercera, otra vez el doble (8) en la cuarta, y así sucesivamente hasta la sexagésima cuarta casilla del tablero. + Haga un algoritmo que calcule la cantidad total de granos de trigo necesarios para realizar esta distribución. La función ``suma_granos`` devolverá + esta cantidad. Su parámetro ``n`` será el valor ``64``, representando el número de casillas de un tablero de ajedrez. |br| + + ~~~~ + def suma_granos(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(suma_granos(64), 18446744073709551615, "Esperado: 18446744073709551615") + + + myTests().main() + + + .. tab:: Ejercicio 5 + + .. activecode:: qExtra_5 + :nocodelens: + + Se dan ``n`` baldosas con dimensión de 10cm x 10cm. Con ellas, usted debe ensamblar un conjunto de cuadrados usando todas las baldosas dadas. Para ello, debe seguir las siguientes reglas: + + - El primer cuadrado que se construya debe usar la mayor cantidad de baldosas posibles. + - Si quedan baldosas, el siguiente cuadrado también debe construirse con la mayor cantidad de las baldosas que quedaron. + - Seguir este mismo patrón hasta haber usado todas las baldosas. + + Entonces, la función ``forma_cuadrados`` devuelve un **diccionario** representando el conjunto de cuadrados formados. Sus llaves representan el tamaño, en baldosas, del lado del + cuadrado formado, mientras que los valores representan la cantidad de cuadrados de ese tamaño que fueron formados. |br| |br| + Ejemplo: |br| + ``forma_cuadrados(31)`` -> ``{5:1, 2:1, 1:2}`` |br| + **Explicación**: El conjunto formado tendrá 4 cuadrados: 1 cuadrado con 5 baldosas por lado, 1 con 2 baldosas por lado, y 2 con 1 baldosa. |br| + + ~~~~ + def forma_cuadrados(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(forma_cuadrados(31), {5: 1, 2: 1, 1: 2}, "Esperado: {5:1,2:1,1:2}") + self.assertEqual(forma_cuadrados(76), {8: 1, 3: 1, 1: 3}, "Esperado: {8:1,3:1,1:3}") + self.assertEqual(forma_cuadrados(290), {17: 1, 1: 1}, "Esperado: {17:1,1:1}") + self.assertEqual(forma_cuadrados(347), {18: 1, 4: 1, 2: 1, 1: 3}, "Esperado: {18:1,4:1,2:1,1:3}") + + + myTests().main() diff --git a/293/_sources/quiz/QuizExtras2.rst.txt b/293/_sources/quiz/QuizExtras2.rst.txt new file mode 100644 index 0000000000..51bf4b8e37 --- /dev/null +++ b/293/_sources/quiz/QuizExtras2.rst.txt @@ -0,0 +1,122 @@ +=============== +Quiz - Extras 2 +=============== + +.. |br| raw:: html + +
+ + +.. tabbed:: quizExtra2 + + .. tab:: Ejercicio 1 + + .. activecode:: qExtra2_1 + :nocodelens: + + Una escuela primaria tiene planeado hacer una visita al zoológico a algunos de sus alumnos. Para esto la escuela solo puede gastar exactamente ``presupuesto`` unidades. Se sabe que la entrada al zoológico cuesta 5 unidades para menores de 12 años y 7 unidades para los que tengan 12 años o más. Desarrolle la función ``maximo_estudiantes`` que recibe ``presupuesto`` un entero positivo que indica el presupuesto que pretende gasta la escuela. La función debe devolver una tupla ``(p, g)`` con el número máximo pequeños y grandes alumnos que la escuela puede llevar al zoológico considerando todos los valores como enteros. |br| |br| + ~~~~ + def maximo_estudiantes(presupuesto): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + maximo_estudiantes(93), (13, 4), + "Esperado: 13 pequeños y 4 grandes" + ) + self.assertEqual( + maximo_estudiantes(63), (7, 4), + "Esperado: 7 pequeños y 4 grandes" + ) + + + myTests().main() + + + .. tab:: Ejercicio 2 + + .. activecode:: qExtra2_2 + :nocodelens: + + Desarrolle la función ``a_romano`` que recibe un entero ``n`` positivo mayor que cero. La función debe devolver la conversión del número en sistema arábigo al sistema a romano. La función debe devolver una cadena que represente el número en romano. |br| |br| + Ejemplos: |br| + ``a_romano(5)`` -> ``"V"`` |br| + ``a_romano(10)`` -> ``"X"`` |br| + ``a_romano(25)`` -> ``"XXV"`` |br| + ``a_romano(2011)`` -> ``"MMXI"`` |br| + ~~~~ + def a_romano(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(a_romano(12), "XII", "Esperado: XII") + self.assertEqual(a_romano(123), "CXXIII", "Esperado: CXXIII") + self.assertEqual(a_romano(400), "CD", "Esperado: CD") + self.assertEqual(a_romano(84), "LXXXIV", "Esperado: LXXXIV") + self.assertEqual(a_romano(542), "DXLII", "Esperado: DXLII") + self.assertEqual(a_romano(1042), "MXLII", "Esperado: MXLII") + self.assertEqual(a_romano(49), "XLIX", "Esperado: XLIX") + self.assertEqual(a_romano(429), "CDXXIX", "Esperado: CDXXIX") + self.assertEqual(a_romano(367), "CCCLXVII", "Esperado: CCCLXVII") + self.assertEqual(a_romano(23), "XXIII", "Esperado: XXIII") + self.assertEqual(a_romano(257), "CCLVII", "Esperado: CCLVII") + self.assertEqual(a_romano(968), "CMLXVIII", "Esperado: CMLXVIII") + + + myTests().main() + + + .. tab:: Ejercicio 3 + + .. activecode:: qExtra2_3 + :nocodelens: + + Desarrolle la función ``calcular_pi`` que recibe un parámetro ``n`` positivo mayor a 0. La función debe calcular el valor aproximado de ``pi`` con ``n`` terminos, de acuerdo con la siguiente fórmula. |br| + + ``pi = (4/1) - (4/3) + (4/5) - (4/7) ...`` |br| + + El resultado debe ser redondeado a 2 decimales y devuelto como una cadena. |br| |br| + + Ejemplos: |br| + ``calcular_pi(4)`` -> ``"2.90"`` |br| + *Explicación*: Los primero 4 términos siguiendo la formula son: ``(4/1) - (4/3) + (4/5) - (4/7)`` que dan como resultado ``2.895238095``, redondeando a dos decimales el resultado final sería ``2.90`` |br| + ``calcular_pi(24)`` -> ``"3.10"`` |br| + ``calcular_pi(61)`` -> ``"3.16"`` |br| + ``calcular_pi(100)`` -> ``"3.13"`` |br| + + ~~~~ + def calcular_pi(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(calcular_pi(4), "2.90", "Esperado: 2.90") + self.assertEqual(calcular_pi(10), "3.04", "Esperado: 3.04") + self.assertEqual(calcular_pi(15), "3.21", "Esperado: 3.21") + self.assertEqual(calcular_pi(60), "3.12", "Esperado: 3.12") + self.assertEqual(calcular_pi(24), "3.10", "Esperado: 3.10") + self.assertEqual(calcular_pi(100), "3.13", "Esperado: 3.13") + self.assertEqual(calcular_pi(1000), "3.14", "Esperado: 3.14") + + + myTests().main() diff --git a/293/_sources/quiz/QuizExtras2_en.rst.txt b/293/_sources/quiz/QuizExtras2_en.rst.txt new file mode 100644 index 0000000000..018ca649d3 --- /dev/null +++ b/293/_sources/quiz/QuizExtras2_en.rst.txt @@ -0,0 +1,122 @@ +=============== +Quiz - Extras 2 +=============== + +.. |br| raw:: html + +
+ + +.. tabbed:: quizExtra2 + + .. tab:: Exercise 1 + + .. activecode:: qExtra2_1_en + :nocodelens: + + A primary school is planning a field trip to the zoo for some of its students. For this, the school can only spend exactly ``budget`` units. It is known that the entry to the zoo costs 5 units for children under 12 years old and 7 units for those who are 12 years old or older. Develop the function ``maximo_estudiantes`` that receives ``budget``, a positive integer that indicates the budget that the school intends to spend. The function should return a tuple ``(p, g)`` with the maximum number of small and large students that the school can take to the zoo considering all values as integers. |br| |br| + ~~~~ + def maximo_estudiantes(budget): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual( + maximo_estudiantes(93), (13, 4), + "Expected: 13 small and 4 large" + ) + self.assertEqual( + maximo_estudiantes(63), (7, 4), + "Expected: 7 small and 4 large" + ) + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: qExtra2_2_en + :nocodelens: + + Develop the function ``a_romano``, which receives a positive integer ``n`` greater than zero. The function should return the conversion of the number from Arabic to Roman numerals. The function should return a string that represents the number in Roman numerals. |br| |br| + Examples: |br| + ``a_romano(5)`` -> ``"V"`` |br| + ``a_romano(10)`` -> ``"X"`` |br| + ``a_romano(25)`` -> ``"XXV"`` |br| + ``a_romano(2011)`` -> ``"MMXI"`` |br| + ~~~~ + def a_romano(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(a_romano(12), "XII", "Expected: XII") + self.assertEqual(a_romano(123), "CXXIII", "Expected: CXXIII") + self.assertEqual(a_romano(400), "CD", "Expected: CD") + self.assertEqual(a_romano(84), "LXXXIV", "Expected: LXXXIV") + self.assertEqual(a_romano(542), "DXLII", "Expected: DXLII") + self.assertEqual(a_romano(1042), "MXLII", "Expected: MXLII") + self.assertEqual(a_romano(49), "XLIX", "Expected: XLIX") + self.assertEqual(a_romano(429), "CDXXIX", "Expected: CDXXIX") + self.assertEqual(a_romano(367), "CCCLXVII", "Expected: CCCLXVII") + self.assertEqual(a_romano(23), "XXIII", "Expected: XXIII") + self.assertEqual(a_romano(257), "CCLVII", "Expected: CCLVII") + self.assertEqual(a_romano(968), "CMLXVIII", "Expected: CMLXVIII") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: qExtra2_3_en + :nocodelens: + + Develop the function ``calcular_pi``, which receives a positive parameter ``n`` greater than 0. The function should calculate the approximate value of ``pi`` with ``n`` terms, according to the following formula. |br| + + ``pi = (4/1) - (4/3) + (4/5) - (4/7) ...`` |br| + + The result should be rounded to 2 decimals and returned as a string. |br| |br| + + Examples: |br| + ``calcular_pi(4)`` -> ``"2.90"`` |br| + *Explanation*: The first 4 terms following the formula are: ``(4/1) - (4/3) + (4/5) - (4/7)`` which result in ``2.895238095``, rounding to two decimal places the final result would be ``2.90`` |br| + ``calcular_pi(24)`` -> ``"3.10"`` |br| + ``calcular_pi(61)`` -> ``"3.16"`` |br| + ``calcular_pi(100)`` -> ``"3.13"`` |br| + + ~~~~ + def calcular_pi(n): + + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(calcular_pi(4), "2.90", "Expected: 2.90") + self.assertEqual(calcular_pi(10), "3.04", "Expected: 3.04") + self.assertEqual(calcular_pi(15), "3.21", "Expected: 3.21") + self.assertEqual(calcular_pi(60), "3.12", "Expected: 3.12") + self.assertEqual(calcular_pi(24), "3.10", "Expected: 3.10") + self.assertEqual(calcular_pi(100), "3.13", "Expected: 3.13") + self.assertEqual(calcular_pi(1000), "3.14", "Expected: 3.14") + + + myTests().main() \ No newline at end of file diff --git a/293/_sources/quiz/QuizExtras_en.rst.txt b/293/_sources/quiz/QuizExtras_en.rst.txt new file mode 100644 index 0000000000..3ac64c6356 --- /dev/null +++ b/293/_sources/quiz/QuizExtras_en.rst.txt @@ -0,0 +1,171 @@ +============= +Quiz - Extras +============= + +.. |br| raw:: html + +
+ +.. tabbed:: quizExtras + + .. tab:: Exercise 1 + + .. activecode:: qExtra_1_en + :nocodelens: + + **Josephus problem**. Imagine you have ``n`` people arranged in a circle. Suppose these people are numbered from 1 to ``n`` clockwise. Starting with person number **1**, + run the circle clockwise and eliminate every ``m``-th person, as long as the circle has two or more people. The challenge is to develop the ``josephus`` function + that takes ``n`` and ``m`` as parameters, both positive integers. The function should return the number of the person in the circle who survived. |br| |br| + + ~~~~ + def josephus(n, m): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(josephus(50, 3), 11, "Expected: 11") + + + myTests().main() + + + .. tab:: Exercise 2 + + .. activecode:: qExtra_2_en + :nocodelens: + + Implement the **Sieve of Eratosthenes** algorithm. |br| + `Sieve of Eratosthenes `_ |br| + The challenge is to develop the ``eratosthenes_sieve`` function that takes ``n``, a positive integer, as a parameter + and returns the number of prime numbers in the interval **[2, n]**. Use the Sieve of Eratosthenes to solve this problem. |br| |br| + Examples: |br| + ``eratosthenes_sieve(20)`` -> ``8`` |br| + ``eratosthenes_sieve(12)`` -> ``5`` |br| + + ~~~~ + def eratosthenes_sieve(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(eratosthenes_sieve(20), 8, "Expected: 8") + self.assertEqual(eratosthenes_sieve(12), 5, "Expected: 5") + self.assertEqual(eratosthenes_sieve(30), 10, "Expected: 10") + self.assertEqual(eratosthenes_sieve(5), 3, "Expected: 3") + + + myTests().main() + + + .. tab:: Exercise 3 + + .. activecode:: qExtra_3_en + :nocodelens: + + **Project Euler Problem 2**. `Problem `_ |br| + First, check what the ``yield`` keyword does in Python. Then, solve the adaptation of Project Euler Problem 2 below: |br| + Develop the ``p_euler`` function that takes ``n``, a positive integer, as an argument, and returns the sum of all even numbers less than ``n`` + in the Fibonacci sequence of ``n``. |br| |br| + Example: |br| + ``p_euler(10)`` -> ``10`` |br| + **Explanation**: The first ten terms of the Fibonacci sequence are:: + + 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 + + Therefore, the even numbers in this sequence are:: + + 2, 8, 34 + + However, only ``2`` and ``8`` meet the condition of being less than ``n`` (in this case less than 10). The sum of these is ``10``. + + ~~~~ + def p_euler(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(p_euler(4000000), 4613732, "Expected: 4613732") + self.assertEqual(p_euler(10), 10, "Expected: 10") + self.assertEqual(p_euler(100), 44, "Expected: 44") + + + myTests().main() + + + .. tab:: Exercise 4 + + .. activecode:: qExtra_4_en + :nocodelens: + + In the book "The Man Who Counted," by *Malba Tahan*, a character wanted to win the grains of wheat that were distributed on a chessboard as follows: + one grain in the first square of the board, double (2) in the second, again double (4) in the third, again double (8) in the fourth, and so on up to the sixty-fourth square of the board. + Write an algorithm that calculates the total number of wheat grains needed to make this distribution. The ``sum_grains`` function will return + this amount. The parameter ``n`` will be the value ``64``, representing the number of squares on a chessboard. |br| + + ~~~~ + def sum_grains(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(sum_grains(64), 18446744073709551615, "Expected: 18446744073709551615") + + + myTests().main() + + + .. tab:: Exercise 5 + + .. activecode:: qExtra_5_en + :nocodelens: + + You are given ``n`` tiles with dimensions of 10cm x 10cm. With them, you must assemble a set of squares using all the given tiles. To do this, you must follow the following rules: + + - The first square you build should use as many tiles as possible. + - If there are tiles left, the next square should also be built using the largest possible number of tiles that remain. + - Follow this same pattern until all tiles are used. + + Then, the ``form_squares`` function returns a **dictionary** representing the set of formed squares. Its keys represent the size, in tiles, of the side of the + formed square, while the values represent the quantity of squares of that size that were formed. |br| |br| + Example: |br| + ``form_squares(31)`` -> ``{5:1, 2:1, 1:2}`` |br| + **Explanation**: The formed set will have 4 squares: 1 square with 5 tiles per side, 1 with 2 tiles per side, and 2 with 1 tile per side. |br| + + ~~~~ + def form_squares(n): + + + ==== + from unittest.gui import TestCaseGui + + + class myTests(TestCaseGui): + def testOne(self): + + self.assertEqual(form_squares(31), {5: 1, 2: 1, 1: 2}, "Expected: {5:1,2:1,1:2}") + self.assertEqual(form_squares(76), {8: 1, 3: 1, 1: 3}, "Expected: {8:1,3:1,1:3}") + self.assertEqual(form_squares(290), {17: 1, 1: 1}, "Expected: {17:1,1:1}") + self.assertEqual(form_squares(347), {18: 1, 4: 1, 2: 1, 1: 3}, "Expected: {18:1,4:1,2:1,1:3}") + + + myTests().main() \ No newline at end of file diff --git a/293/_static/060b2710bdbbe3dfe48b.svg b/293/_static/060b2710bdbbe3dfe48b.svg new file mode 100644 index 0000000000..94fb5490a2 --- /dev/null +++ b/293/_static/060b2710bdbbe3dfe48b.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/293/_static/4692b9ec53fd5972caa2.ttf b/293/_static/4692b9ec53fd5972caa2.ttf new file mode 100644 index 0000000000..1413fc609a Binary files /dev/null and b/293/_static/4692b9ec53fd5972caa2.ttf differ diff --git a/293/_static/5be1347c682810f199c7.eot b/293/_static/5be1347c682810f199c7.eot new file mode 100644 index 0000000000..b93a4953ff Binary files /dev/null and b/293/_static/5be1347c682810f199c7.eot differ diff --git a/293/_static/82b1212e45a2bc35dd73.woff b/293/_static/82b1212e45a2bc35dd73.woff new file mode 100644 index 0000000000..9e612858f8 Binary files /dev/null and b/293/_static/82b1212e45a2bc35dd73.woff differ diff --git a/293/_static/BlueBar1.jpg b/293/_static/BlueBar1.jpg new file mode 100644 index 0000000000..1a378f716a Binary files /dev/null and b/293/_static/BlueBar1.jpg differ diff --git a/293/_static/Chinook_Sqlite.sqlite b/293/_static/Chinook_Sqlite.sqlite new file mode 100644 index 0000000000..b559c7394a Binary files /dev/null and b/293/_static/Chinook_Sqlite.sqlite differ diff --git a/293/_static/CodeChat.css b/293/_static/CodeChat.css new file mode 100644 index 0000000000..cab874f797 --- /dev/null +++ b/293/_static/CodeChat.css @@ -0,0 +1,56 @@ +/* +.. Copyright (C) 2012-2020 Bryan A. Jones. + + This file is part of CodeChat. + + CodeChat is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + CodeChat is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with CodeChat. If not, see . + +********************************************** +|docname| - Style sheet for CodeChat documents +********************************************** +This is a style sheet for use with CodeChat's extensions to Docutils/Sphinx. + +The overall goal is to allow comments (everything but ``
`` tags) to appear with normal (double) spacing, while comments and code are single spaced.
+
+This import will cause an error if the Docutils ``html4css1`` style sheet is embedded instead of linked, though the page still displays without problems. However, omitting it will cause the linked style sheet case to fail, so leave this in.
+*/
+@import url(html4css1.css);
+
+/* Remove all top and bottom space around ``
``, making it single-spaced. Also, remove the border so that code and comments mix more naturally. */
+.fenced-code pre,
+div.fenced-code div.highlight,
+div.fenced-code div.highlight pre,
+pre.fenced-code,
+div[class*="highlight-"] {
+    padding-top: 0px;
+    padding-bottom: 0px;
+    padding-left: 0px;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-left: 0px;
+    border: none;
+    -webkit-box-shadow: none;
+}
+
+/* Remove the space between code and a following comment. This style will be added to comments following code by JavaScript; see ``CodeChat.SourceClassifer.codechat_style``. */
+.CodeChat_noTop {
+    margin-top: 0px;
+    padding-top: 0px;
+}
+
+/* Remove the space between a comment and the following code. This style will be added to comments preceeding code JavaScript; see ``CodeChat.SourceClassifer.codechat_style``. */
+.CodeChat_noBottom {
+    margin-bottom: 0px;
+    padding-bottom: 0px;
+}
diff --git a/293/_static/CodeChat_sphinx_rtd_theme.css b/293/_static/CodeChat_sphinx_rtd_theme.css
new file mode 100644
index 0000000000..ba7b0bc9f5
--- /dev/null
+++ b/293/_static/CodeChat_sphinx_rtd_theme.css
@@ -0,0 +1,31 @@
+/* .. Copyright (C) 2012-2020 Bryan A. Jones.
+
+    This file is part of CodeChat.
+
+    CodeChat is free software: you can redistribute it and/or modify it under
+    the terms of the GNU General Public License as published by the Free
+    Software Foundation, either version 3 of the License, or (at your option)
+    any later version.
+
+    CodeChat is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+    details.
+
+    You should have received a copy of the GNU General Public License along
+    with CodeChat.  If not, see .
+
+   ******************************************************************
+   |docname| - Style sheet for CodeChat with the `ReadTheDocs theme`_
+   ******************************************************************
+   This style sheet fixes the size of CodeChat's indent so that code and comments line up when using the `ReadTheDocs theme `_. This is only needed for the `ReadTheDocs theme`_. To use it, add the following to your project's ``conf.py``:
+
+   .. code-block::
+    :linenos:
+
+    html_css_files = ['CodeChat_sphinx_rtd_theme.css']
+ */
+div.CodeChat-indent {
+    font-size: 10pt;
+}
+
diff --git a/293/_static/FileSaver.min.js b/293/_static/FileSaver.min.js
new file mode 100644
index 0000000000..eb062f2590
--- /dev/null
+++ b/293/_static/FileSaver.min.js
@@ -0,0 +1,2 @@
+/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
+var saveAs=saveAs||function(view){"use strict";if(typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var doc=view.document,get_URL=function(){return view.URL||view.webkitURL||view},save_link=doc.createElementNS("http://www.w3.org/1999/xhtml","a"),can_use_save_link="download"in save_link,click=function(node){var event=new MouseEvent("click");node.dispatchEvent(event)},is_safari=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),webkit_req_fs=view.webkitRequestFileSystem,req_fs=view.requestFileSystem||webkit_req_fs||view.mozRequestFileSystem,throw_outside=function(ex){(view.setImmediate||view.setTimeout)(function(){throw ex},0)},force_saveable_type="application/octet-stream",fs_min_size=0,arbitrary_revoke_timeout=500,revoke=function(file){var revoker=function(){if(typeof file==="string"){get_URL().revokeObjectURL(file)}else{file.remove()}};if(view.chrome){revoker()}else{setTimeout(revoker,arbitrary_revoke_timeout)}},dispatch=function(filesaver,event_types,event){event_types=[].concat(event_types);var i=event_types.length;while(i--){var listener=filesaver["on"+event_types[i]];if(typeof listener==="function"){try{listener.call(filesaver,event||filesaver)}catch(ex){throw_outside(ex)}}}},auto_bom=function(blob){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)){return new Blob(["\ufeff",blob],{type:blob.type})}return blob},FileSaver=function(blob,name,no_auto_bom){if(!no_auto_bom){blob=auto_bom(blob)}var filesaver=this,type=blob.type,blob_changed=false,object_url,target_view,dispatch_all=function(){dispatch(filesaver,"writestart progress write writeend".split(" "))},fs_error=function(){if(target_view&&is_safari&&typeof FileReader!=="undefined"){var reader=new FileReader;reader.onloadend=function(){var base64Data=reader.result;target_view.location.href="data:attachment/file"+base64Data.slice(base64Data.search(/[,;]/));filesaver.readyState=filesaver.DONE;dispatch_all()};reader.readAsDataURL(blob);filesaver.readyState=filesaver.INIT;return}if(blob_changed||!object_url){object_url=get_URL().createObjectURL(blob)}if(target_view){target_view.location.href=object_url}else{var new_tab=view.open(object_url,"_blank");if(new_tab==undefined&&is_safari){view.location.href=object_url}}filesaver.readyState=filesaver.DONE;dispatch_all();revoke(object_url)},abortable=function(func){return function(){if(filesaver.readyState!==filesaver.DONE){return func.apply(this,arguments)}}},create_if_not_found={create:true,exclusive:false},slice;filesaver.readyState=filesaver.INIT;if(!name){name="download"}if(can_use_save_link){object_url=get_URL().createObjectURL(blob);setTimeout(function(){save_link.href=object_url;save_link.download=name;click(save_link);dispatch_all();revoke(object_url);filesaver.readyState=filesaver.DONE});return}if(view.chrome&&type&&type!==force_saveable_type){slice=blob.slice||blob.webkitSlice;blob=slice.call(blob,0,blob.size,force_saveable_type);blob_changed=true}if(webkit_req_fs&&name!=="download"){name+=".download"}if(type===force_saveable_type||webkit_req_fs){target_view=view}if(!req_fs){fs_error();return}fs_min_size+=blob.size;req_fs(view.TEMPORARY,fs_min_size,abortable(function(fs){fs.root.getDirectory("saved",create_if_not_found,abortable(function(dir){var save=function(){dir.getFile(name,create_if_not_found,abortable(function(file){file.createWriter(abortable(function(writer){writer.onwriteend=function(event){target_view.location.href=file.toURL();filesaver.readyState=filesaver.DONE;dispatch(filesaver,"writeend",event);revoke(file)};writer.onerror=function(){var error=writer.error;if(error.code!==error.ABORT_ERR){fs_error()}};"writestart progress write abort".split(" ").forEach(function(event){writer["on"+event]=filesaver["on"+event]});writer.write(blob);filesaver.abort=function(){writer.abort();filesaver.readyState=filesaver.DONE};filesaver.readyState=filesaver.WRITING}),fs_error)}),fs_error)};dir.getFile(name,{create:false},abortable(function(file){file.remove();save()}),abortable(function(ex){if(ex.code===ex.NOT_FOUND_ERR){save()}else{fs_error()}}))}),fs_error)}),fs_error)},FS_proto=FileSaver.prototype,saveAs=function(blob,name,no_auto_bom){return new FileSaver(blob,name,no_auto_bom)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(blob,name,no_auto_bom){if(!no_auto_bom){blob=auto_bom(blob)}return navigator.msSaveOrOpenBlob(blob,name||"download")}}FS_proto.abort=function(){var filesaver=this;filesaver.readyState=filesaver.DONE;dispatch(filesaver,"abort")};FS_proto.readyState=FS_proto.INIT=0;FS_proto.WRITING=1;FS_proto.DONE=2;FS_proto.error=FS_proto.onwritestart=FS_proto.onprogress=FS_proto.onwrite=FS_proto.onabort=FS_proto.onerror=FS_proto.onwriteend=null;return saveAs}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!=null){define([],function(){return saveAs})}
diff --git a/293/_static/accessibility.css b/293/_static/accessibility.css
new file mode 100644
index 0000000000..3e39702c8e
--- /dev/null
+++ b/293/_static/accessibility.css
@@ -0,0 +1,155 @@
+/*
+**********************************************
+|docname| - a WCAG 2.0 AA compliant stylesheet
+**********************************************
+*/
+
+/* Variables holding theme colors */
+:root {
+	--codebuttons: #474949;
+}
+[data-theme="dark"] {
+	--codebuttons: #2c0aa6;
+}
+/*Navigation Tabbing Styling*/
+li.dropdown.open a.dropdown-toggle, li.dropdown.open a.dropdown-toggle:focus {
+	border:0px !important;
+	/*background-color: #346A6E!important;*/
+	background-color: #2A5659 !important;
+	color:#F8F8F8 !important;
+}
+a.dropdown-toggle:focus {
+	 /*border:1px solid #5B9DD9 !important;
+	 color:#5B9DD9 !important;
+	 width:48px !important;*/
+	 background-color: #52A6AC!important;
+	 color:#F8F8F8 !important;
+}
+/* Border Manipulation */
+li.divider-vertical {
+	margin:0px !important;
+}
+li.dropdown a.dropdown-toggle {
+	padding:15px 18px !important;
+}
+
+/*
+Bootstrap button styling
+*/
+
+/* Default Button */
+/* Passes WCAG 2.0 */
+button.btn.btn-default:active {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default:focus {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default{
+	color:#FFFFFF !important;
+	background-color: var(--codebuttons) !important;
+}
+button.btn.btn-default.btn-sm.disabled:active {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default.btn-sm.disabled:focus {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default.btn-sm.disabled{
+	color:#FFFFFF !important;
+	background-color:#474949 !important;
+}
+/* Sucess Button */
+/* Failed WCAG 2.0, #255425 passes */
+button.btn.btn-success:active {
+	color:#427e44 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-success:focus {
+	color:#427e44!important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-success {
+	color:#FFFFFF !important;
+	background-color:#427e44!important;
+}
+
+/*Primary Button*/
+/* fails WCAG 2.0, #265986 passes */
+button.btn.btn-primary:active {
+	color:#3379b6!important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-primary:focus {
+	color:#3379b6 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-primary {
+	color:#FFFFFF !important;
+	background-color:#3379b6 !important;
+}
+
+
+/*Info Button */
+/* Fails, WCAG 2.0, #155569 passes*/
+button.btn.btn-info:active {
+	color:#1a6a83!important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-info:focus {
+	color:#1a6a83 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-info{
+	color:#FFFFFF !important;
+	background-color:#1a6a83 !important;
+}
+
+/*Warning Button*/
+/*Fails WCAG 2.0, #794b0b*/
+button.btn.btn-warning:active {
+	color:#945c0e !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-warning:focus {
+	color:#945c0e !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-warning {
+	color:#FFFFFF !important;
+	background-color:#945c0e !important;
+}
+
+/*Danger Button */
+/*Fails, #a62924 passes*/
+button.btn.btn-danger:active {
+	color:#d33a35 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-danger:focus {
+	color:#d33a35 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-danger{
+	color:#FFFFFF !important;
+	background-color:#d33a35 !important;
+}
+
+/*Link Button*/
+/*Fails AAA, passes with #265986*/
+button.btn.btn-link:active {
+	color:#FFFFFF!important;
+	background-color:#1a6a83 !important;
+}
+button.btn.btn-link:focus {
+	color:#FFFFFF !important;
+	background-color:#1a6a83 !important;
+}
+button.btn.btn-link {
+	color:#1a6a83 !important;
+	background-color:#FFFFFF !important;
+}
\ No newline at end of file
diff --git a/293/_static/accessibilitydarkest.css b/293/_static/accessibilitydarkest.css
new file mode 100644
index 0000000000..8fa24b3bd5
--- /dev/null
+++ b/293/_static/accessibilitydarkest.css
@@ -0,0 +1,148 @@
+/*
+***********************************************************
+|docname| - a WCAG 2.0 AAA compliant stylesheet (dark mode)
+***********************************************************
+*/
+
+/*Navigation Tabbing Styling*/
+li.dropdown.open a.dropdown-toggle, li.dropdown.open a.dropdown-toggle:focus {
+	border:0px !important;
+	/*background-color: #346A6E!important;*/
+	background-color: #2A5659 !important;
+	color:#F8F8F8 !important;
+}
+a.dropdown-toggle:focus {
+	 /*border:1px solid #5B9DD9 !important;
+	 color:#5B9DD9 !important;
+	 width:48px !important;*/
+	 background-color: #52A6AC!important;
+	 color:#F8F8F8 !important;
+}
+/* Border Manipulation */
+li.divider-vertical {
+	margin:0px !important;
+}
+li.dropdown a.dropdown-toggle {
+	padding:15px 18px !important;
+}
+
+/*
+Bootstrap button styling
+*/
+
+/* Default Button */
+/* Passes WCAG 2.0 */
+button.btn.btn-default:active {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default:focus {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default{
+	color:#FFFFFF !important;
+	background-color:#474949 !important;
+}
+button.btn.btn-default.btn-sm.disabled:active {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default.btn-sm.disabled:focus {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default.btn-sm.disabled{
+	color:#FFFFFF !important;
+	background-color:#474949 !important;
+}
+/* Sucess Button */
+/* Failed WCAG 2.0, #255425 passes */
+button.btn.btn-success:active {
+	color:#255425 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-success:focus {
+	color:#255425 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-success {
+	color:#FFFFFF !important;
+	background-color:#255425 !important;
+}
+
+/*Primary Button*/
+/* fails WCAG 2.0, #265986 passes */
+button.btn.btn-primary:active {
+	color:#265986 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-primary:focus {
+	color:#265986 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-primary {
+	color:#FFFFFF !important;
+	background-color:#265986 !important;
+}
+
+
+/*Info Button */
+/* Fails, WCAG 2.0, #155569 passes*/
+button.btn.btn-info:active {
+	color:#155569 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-info:focus {
+	color:#155569  !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-info{
+	color:#FFFFFF !important;
+	background-color:#155569 !important;
+}
+
+/*Warning Button*/
+/*Fails WCAG 2.0, #794b0b*/
+button.btn.btn-warning:active {
+	color:#794b0b !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-warning:focus {
+	color:#794b0b !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-warning {
+	color:#FFFFFF !important;
+	background-color:#794b0b !important;
+}
+
+/*Danger Button */
+/*Fails, #a62924 passes*/
+button.btn.btn-danger:active {
+	color:#a62924 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-danger:focus {
+	color:#a62924 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-danger{
+	color:#FFFFFF !important;
+	background-color: #a62924 !important;
+}
+
+/*Link Button*/
+/*Fails AAA, passes with #265986*/
+button.btn.btn-link:active {
+	color:#FFFFFF!important;
+	background-color:#265986 !important;
+}
+button.btn.btn-link:focus {
+	color:#FFFFFF !important;
+	background-color:#265986 !important;
+}
+button.btn.btn-link {
+	color:#265986 !important;
+	background-color:#FFFFFF !important;
+}
\ No newline at end of file
diff --git a/293/_static/accessibilitylight.css b/293/_static/accessibilitylight.css
new file mode 100644
index 0000000000..7a8717cce1
--- /dev/null
+++ b/293/_static/accessibilitylight.css
@@ -0,0 +1,116 @@
+/*
+********************************************************************************
+|docname| - a stylesheet that doesn't change bootstrap colors but adds inversion
+********************************************************************************
+*/
+
+/*Navigation Tabbing Styling*/
+li.dropdown.open a.dropdown-toggle, li.dropdown.open a.dropdown-toggle:focus {
+	border:0px !important;
+	/*background-color: #346A6E!important;*/
+	background-color: #2A5659 !important;
+	color:#F8F8F8 !important;
+}
+a.dropdown-toggle:focus {
+	 /*border:1px solid #5B9DD9 !important;
+	 color:#5B9DD9 !important;
+	 width:48px !important;*/
+	 background-color: #52A6AC!important;
+	 color:#F8F8F8 !important;
+}
+/* Border Manipulation */
+li.divider-vertical {
+	margin:0px !important;
+}
+li.dropdown a.dropdown-toggle {
+	padding:15px 18px !important;
+}
+
+/*
+Bootstrap button styling
+*/
+
+/* Default Button */
+/* Passes WCAG 2.0 */
+button.btn.btn-default:active {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default:focus {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default.btn-sm.disabled:active {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-default.btn-sm.disabled:focus {
+	color:#474949 !important;
+	background-color:#FFFFFF !important;
+}
+/* Sucess Button */
+/* Failed WCAG 2.0, #255425 passes */
+button.btn.btn-success:active {
+	color:#5CB85C !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-success:focus {
+	color:#5CB85C !important;
+	background-color:#FFFFFF !important;
+}
+
+/*Primary Button*/
+/* fails WCAG 2.0, #265986 passes */
+button.btn.btn-primary:active {
+	color:#337AB7 !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-primary:focus {
+	color:#337AB7 !important;
+	background-color:#FFFFFF !important;
+}
+
+
+/*Info Button */
+/* Fails, WCAG 2.0, #155569 passes*/
+button.btn.btn-info:active {
+	color:#5BC0DE!important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-info:focus {
+	color:#5BC0DE !important;
+	background-color:#FFFFFF !important;
+}
+
+/*Warning Button*/
+/*Fails WCAG 2.0, #794b0b*/
+button.btn.btn-warning:active {
+	color:#F0AD4E !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-warning:focus {
+	color:#F0AD4E !important;
+	background-color:#FFFFFF !important;
+}
+
+/*Danger Button */
+/*Fails, #a62924 passes*/
+button.btn.btn-danger:active {
+	color:#D9534F !important;
+	background-color:#FFFFFF !important;
+}
+button.btn.btn-danger:focus {
+	color:#D9534F !important;
+	background-color:#FFFFFF !important;
+}
+
+/*Link Button*/
+/*Fails AAA, passes with #265986*/
+button.btn.btn-link:active {
+	color:#FFFFFF!important;
+	background-color:#337AB7 !important;
+}
+button.btn.btn-link:focus {
+	color:#FFFFFF !important;
+	background-color:#337AB7 !important;
+}
\ No newline at end of file
diff --git a/293/_static/activecodethumb.png b/293/_static/activecodethumb.png
new file mode 100644
index 0000000000..c23b900464
Binary files /dev/null and b/293/_static/activecodethumb.png differ
diff --git a/293/_static/animationbase.js b/293/_static/animationbase.js
new file mode 100644
index 0000000000..ef240ad71b
--- /dev/null
+++ b/293/_static/animationbase.js
@@ -0,0 +1,204 @@
+Animator = function(m, v, divid)
+{
+   this.model = m
+   this.viewer = v
+   this.timer = null
+   
+   this.cursor = -1
+
+   this.sc = document.getElementById(divid+"_canvas")
+   this.ctx = this.sc.getContext("2d")
+   this.sc.width = this.sc.width
+   this.speed = 75
+
+   this.script = this.model.init()  //does the animation and sends script back 
+   this.viewer.init(this.ctx)
+}
+
+Animator.prototype.getContext=function()
+{
+   return this.ctx
+}
+
+Animator.prototype.incCursor=function()
+{
+   if (this.cursor < this.script.length-1)
+      this.cursor = this.cursor + 1
+}
+
+Animator.prototype.decCursor=function()
+{
+   if (this.cursor > 0)
+      this.cursor = this.cursor -1
+}
+
+Animator.prototype.getCursor=function()
+{
+   return this.cursor
+}
+
+Animator.prototype.setCursor=function(newc)
+{
+   this.cursor = newc
+}
+  
+Animator.prototype.run = function(animobj)
+{
+   if (this.timer == null)
+      this.timer = setInterval(animobj+".forward()",this.speed)
+}
+
+Animator.prototype.stop = function()
+{
+   clearInterval(this.timer)
+   this.timer=null
+}
+
+Animator.prototype.forward = function()
+{ 
+   this.incCursor()
+   this.sc.width = this.sc.width
+   this.viewer.render(this.script[this.getCursor()])
+   if (this.getCursor() == this.script.length-1 && this.timer != null)
+   {
+      clearInterval(this.timer)
+      this.timer = null
+   }
+}
+
+Animator.prototype.backward = function()
+{
+   this.decCursor()
+   this.sc.width = this.sc.width
+   this.viewer.render(this.script[this.getCursor()])
+}
+
+Animator.prototype.end = function()
+{
+   this.setCursor(this.script.length-1)
+   this.sc.width = this.sc.width
+   this.viewer.render(this.script[this.getCursor()])
+
+}
+
+Animator.prototype.begin = function()
+{
+   this.setCursor(0)
+   this.sc.width=this.sc.width
+   this.viewer.render(this.script[this.getCursor()])
+}
+
+Animator.prototype.init = function()
+{
+   this.setCursor(0)
+   this.sc.width = this.sc.width
+   this.viewer.render(this.script[0])
+}
+
+init1 = function()
+{
+   a = new Animator(new BubbleSortModel(), new BarViewer())
+   a.init()
+}
+
+init2 = function()
+{
+   a = new Animator(new BubbleSortModel(), new ScatterViewer())
+   a.init()
+}
+
+init3 = function()
+{
+   a = new Animator(new BubbleSortModel(), new BoxViewer())
+   a.init()
+}
+
+init4 = function()
+{
+   a = new Animator(new SelectionSortModel(), new BarViewer())
+   a.init()
+}
+
+init5 = function()
+{
+   a = new Animator(new SelectionSortModel(), new ScatterViewer())
+   a.init()
+}
+
+init6 = function()
+{
+   a = new Animator(new SelectionSortModel(), new BoxViewer())
+   a.init()
+}
+
+init7 = function()
+{
+   a = new Animator(new InsertionSortModel(), new BarViewer())
+   a.init()
+}
+
+init8 = function()
+{
+   a = new Animator(new InsertionSortModel(), new ScatterViewer())
+   a.init()
+}
+
+init9 = function()
+{
+   a = new Animator(new InsertionSortModel(), new BoxViewer())
+   a.init()
+}
+
+init10 = function()
+{
+   a = new Animator(new ShellSortModel(), new BarViewer())
+   a.init()
+}
+
+init11 = function()
+{
+   a = new Animator(new ShellSortModel(), new ScatterViewer())
+   a.init()
+}
+
+init12 = function()
+{
+   a = new Animator(new ShellSortModel(), new BoxViewer())
+   a.init()
+}
+
+init13 = function()
+{
+   a = new Animator(new MergeSortModel(), new BarViewer())
+   a.init()
+}
+
+init14 = function()
+{
+   a = new Animator(new MergeSortModel(), new ScatterViewer())
+   a.init()
+}
+
+init15 = function()
+{
+   a = new Animator(new MergeSortModel(), new BoxViewer())
+   a.init()
+}
+
+init16 = function()
+{
+   a = new Animator(new QuickSortModel(), new BarViewer())
+   a.init()
+}
+
+init17 = function()
+{
+   a = new Animator(new QuickSortModel(), new ScatterViewer())
+   a.init()
+}
+
+init18 = function()
+{
+   a = new Animator(new QuickSortModel(), new BoxViewer())
+   a.init()
+}
diff --git a/293/_static/audio/Example04_Tour01_Line01.mp3 b/293/_static/audio/Example04_Tour01_Line01.mp3
new file mode 100644
index 0000000000..a29d503c17
Binary files /dev/null and b/293/_static/audio/Example04_Tour01_Line01.mp3 differ
diff --git a/293/_static/audio/Example04_Tour01_Line01.wav b/293/_static/audio/Example04_Tour01_Line01.wav
new file mode 100644
index 0000000000..6fe9d20b41
Binary files /dev/null and b/293/_static/audio/Example04_Tour01_Line01.wav differ
diff --git a/293/_static/audio/Example04_Tour01_Line02.mp3 b/293/_static/audio/Example04_Tour01_Line02.mp3
new file mode 100644
index 0000000000..7028674b8a
Binary files /dev/null and b/293/_static/audio/Example04_Tour01_Line02.mp3 differ
diff --git a/293/_static/audio/Example04_Tour01_Line02.wav b/293/_static/audio/Example04_Tour01_Line02.wav
new file mode 100644
index 0000000000..ed1a486040
Binary files /dev/null and b/293/_static/audio/Example04_Tour01_Line02.wav differ
diff --git a/293/_static/audio/Example04_Tour01_Line03.mp3 b/293/_static/audio/Example04_Tour01_Line03.mp3
new file mode 100644
index 0000000000..bd88e1cf28
Binary files /dev/null and b/293/_static/audio/Example04_Tour01_Line03.mp3 differ
diff --git a/293/_static/audio/Example04_Tour01_Line03.wav b/293/_static/audio/Example04_Tour01_Line03.wav
new file mode 100644
index 0000000000..a760e8b832
Binary files /dev/null and b/293/_static/audio/Example04_Tour01_Line03.wav differ
diff --git a/293/_static/audio/solveMaze.ogg b/293/_static/audio/solveMaze.ogg
new file mode 100644
index 0000000000..89e647b6c9
Binary files /dev/null and b/293/_static/audio/solveMaze.ogg differ
diff --git a/293/_static/basic.css b/293/_static/basic.css
new file mode 100644
index 0000000000..b3bdc00406
--- /dev/null
+++ b/293/_static/basic.css
@@ -0,0 +1,861 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+    clear: both;
+}
+
+div.section::after {
+    display: block;
+    content: '';
+    clear: left;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+    width: 100%;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+    word-wrap: break-word;
+    overflow-wrap : break-word;
+}
+
+div.sphinxsidebar ul {
+    list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox form.search {
+    overflow: hidden;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+    float: left;
+    width: 80%;
+    padding: 0.25em;
+    box-sizing: border-box;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+    float: left;
+    width: 20%;
+    border-left: none;
+    padding: 0.25em;
+    box-sizing: border-box;
+}
+
+
+img {
+    border: 0;
+    max-width: 100%;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+    width: 90%;
+    margin-left: auto;
+    margin-right: auto;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+    width: 100%;
+}
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable ul {
+    margin-top: 0;
+    margin-bottom: 0;
+    list-style-type: none;
+}
+
+table.indextable > tbody > tr > td > ul {
+    padding-left: 0em;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+div.modindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+/* -- domain module index --------------------------------------------------- */
+
+table.modindextable td {
+    padding: 2px;
+    border-collapse: collapse;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+div.body {
+    min-width: 450px;
+    max-width: 800px;
+}
+
+div.body p, div.body dd, div.body li, div.body blockquote {
+    -moz-hyphens: auto;
+    -ms-hyphens: auto;
+    -webkit-hyphens: auto;
+    hyphens: auto;
+}
+
+a.headerlink {
+    visibility: hidden;
+}
+
+a.brackets:before,
+span.brackets > a:before{
+    content: "[";
+}
+
+a.brackets:after,
+span.brackets > a:after {
+    content: "]";
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink,
+caption:hover > a.headerlink,
+p.caption:hover > a.headerlink,
+div.code-block-caption:hover > a.headerlink {
+    visibility: visible;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div.body td {
+    text-align: left;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+img.align-left, figure.align-left, .figure.align-left, object.align-left {
+    clear: left;
+    float: left;
+    margin-right: 1em;
+}
+
+img.align-right, figure.align-right, .figure.align-right, object.align-right {
+    clear: right;
+    float: right;
+    margin-left: 1em;
+}
+
+img.align-center, figure.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+img.align-default, figure.align-default, .figure.align-default {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.align-left {
+    text-align: left;
+}
+
+.align-center {
+    text-align: center;
+}
+
+.align-default {
+    text-align: center;
+}
+
+.align-right {
+    text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar,
+aside.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 1px solid #ddb;
+    padding: 7px;
+    background-color: #ffe;
+    width: 40%;
+    float: right;
+    clear: right;
+    overflow-x: auto;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+div.admonition, div.topic, blockquote {
+    clear: left;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+    border: 1px solid #ccc;
+    padding: 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+/* -- content of sidebars/topics/admonitions -------------------------------- */
+
+div.sidebar > :last-child,
+aside.sidebar > :last-child,
+div.topic > :last-child,
+div.admonition > :last-child {
+    margin-bottom: 0;
+}
+
+div.sidebar::after,
+aside.sidebar::after,
+div.topic::after,
+div.admonition::after,
+blockquote::after {
+    display: block;
+    content: '';
+    clear: both;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    border: 0;
+    border-collapse: collapse;
+}
+
+table.align-center {
+    margin-left: auto;
+    margin-right: auto;
+}
+
+table.align-default {
+    margin-left: auto;
+    margin-right: auto;
+}
+
+table caption span.caption-number {
+    font-style: italic;
+}
+
+table caption span.caption-text {
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 5px;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+table.citation {
+    border-left: solid 1px gray;
+    margin-left: 1px;
+}
+
+table.citation td {
+    border-bottom: none;
+}
+
+th > :first-child,
+td > :first-child {
+    margin-top: 0px;
+}
+
+th > :last-child,
+td > :last-child {
+    margin-bottom: 0px;
+}
+
+/* -- figures --------------------------------------------------------------- */
+
+div.figure, figure {
+    margin: 0.5em;
+    padding: 0.5em;
+}
+
+div.figure p.caption, figcaption {
+    padding: 0.3em;
+}
+
+div.figure p.caption span.caption-number,
+figcaption span.caption-number {
+    font-style: italic;
+}
+
+div.figure p.caption span.caption-text,
+figcaption span.caption-text {
+}
+
+/* -- field list styles ----------------------------------------------------- */
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+.field-name {
+    -moz-hyphens: manual;
+    -ms-hyphens: manual;
+    -webkit-hyphens: manual;
+    hyphens: manual;
+}
+
+/* -- hlist styles ---------------------------------------------------------- */
+
+table.hlist {
+    margin: 1em 0;
+}
+
+table.hlist td {
+    vertical-align: top;
+}
+
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+    list-style: decimal;
+}
+
+ol.loweralpha {
+    list-style: lower-alpha;
+}
+
+ol.upperalpha {
+    list-style: upper-alpha;
+}
+
+ol.lowerroman {
+    list-style: lower-roman;
+}
+
+ol.upperroman {
+    list-style: upper-roman;
+}
+
+:not(li) > ol > li:first-child > :first-child,
+:not(li) > ul > li:first-child > :first-child {
+    margin-top: 0px;
+}
+
+:not(li) > ol > li:last-child > :last-child,
+:not(li) > ul > li:last-child > :last-child {
+    margin-bottom: 0px;
+}
+
+ol.simple ol p,
+ol.simple ul p,
+ul.simple ol p,
+ul.simple ul p {
+    margin-top: 0;
+}
+
+ol.simple > li:not(:first-child) > p,
+ul.simple > li:not(:first-child) > p {
+    margin-top: 0;
+}
+
+ol.simple p,
+ul.simple p {
+    margin-bottom: 0;
+}
+
+dl.footnote > dt,
+dl.citation > dt {
+    float: left;
+    margin-right: 0.5em;
+}
+
+dl.footnote > dd,
+dl.citation > dd {
+    margin-bottom: 0em;
+}
+
+dl.footnote > dd:after,
+dl.citation > dd:after {
+    content: "";
+    clear: both;
+}
+
+dl.field-list {
+    display: grid;
+    grid-template-columns: fit-content(30%) auto;
+}
+
+dl.field-list > dt {
+    font-weight: bold;
+    word-break: break-word;
+    padding-left: 0.5em;
+    padding-right: 5px;
+}
+
+dl.field-list > dt:after {
+    content: ":";
+}
+
+dl.field-list > dd {
+    padding-left: 0.5em;
+    margin-top: 0em;
+    margin-left: 0em;
+    margin-bottom: 0em;
+}
+
+dl {
+    margin-bottom: 15px;
+}
+
+dd > :first-child {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+dl > dd:last-child,
+dl > dd:last-child > :last-child {
+    margin-bottom: 0;
+}
+
+dt:target, span.highlighted {
+    background-color: #fbe54e;
+}
+
+rect.highlighted {
+    fill: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.sig-paren {
+    font-size: larger;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+.footnote:target  {
+    background-color: #ffa;
+}
+
+.line-block {
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+.line-block .line-block {
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+    font-family: sans-serif;
+}
+
+.accelerator {
+    text-decoration: underline;
+}
+
+.classifier {
+    font-style: oblique;
+}
+
+.classifier:before {
+    font-style: normal;
+    margin: 0.5em;
+    content: ":";
+}
+
+abbr, acronym {
+    border-bottom: dotted 1px;
+    cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+    overflow: auto;
+    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
+}
+
+pre, div[class*="highlight-"] {
+    clear: both;
+}
+
+span.pre {
+    -moz-hyphens: none;
+    -ms-hyphens: none;
+    -webkit-hyphens: none;
+    hyphens: none;
+}
+
+div[class*="highlight-"] {
+    margin: 1em 0;
+}
+
+td.linenos pre {
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    display: block;
+}
+
+table.highlighttable tbody {
+    display: block;
+}
+
+table.highlighttable tr {
+    display: flex;
+}
+
+table.highlighttable td {
+    margin: 0;
+    padding: 0;
+}
+
+table.highlighttable td.linenos {
+    padding-right: 0.5em;
+}
+
+table.highlighttable td.code {
+    flex: 1;
+    overflow: hidden;
+}
+
+.highlight .hll {
+    display: block;
+}
+
+div.highlight pre,
+table.highlighttable pre {
+    margin: 0;
+}
+
+div.code-block-caption + div {
+    margin-top: 0;
+}
+
+div.code-block-caption {
+    margin-top: 1em;
+    padding: 2px 5px;
+    font-size: small;
+}
+
+div.code-block-caption code {
+    background-color: transparent;
+}
+
+table.highlighttable td.linenos,
+span.linenos,
+div.doctest > div.highlight span.gp {  /* gp: Generic.Prompt */
+    user-select: none;
+}
+
+div.code-block-caption span.caption-number {
+    padding: 0.1em 0.3em;
+    font-style: italic;
+}
+
+div.code-block-caption span.caption-text {
+}
+
+div.literal-block-wrapper {
+    margin: 1em 0;
+}
+
+code.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+code.descclassname {
+    background-color: transparent;
+}
+
+code.xref, a code {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+    background-color: transparent;
+}
+
+.viewcode-link {
+    float: right;
+}
+
+.viewcode-back {
+    float: right;
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    margin: -1px -10px;
+    padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+    vertical-align: middle;
+}
+
+div.body div.math p {
+    text-align: center;
+}
+
+span.eqno {
+    float: right;
+}
+
+span.eqno a.headerlink {
+    position: absolute;
+    z-index: 1;
+}
+
+div.math:hover a.headerlink {
+    visibility: visible;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0 !important;
+        width: 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    #top-link {
+        display: none;
+    }
+}
\ No newline at end of file
diff --git a/293/_static/be810be3a3e14c682a25.woff2 b/293/_static/be810be3a3e14c682a25.woff2
new file mode 100644
index 0000000000..64539b54c3
Binary files /dev/null and b/293/_static/be810be3a3e14c682a25.woff2 differ
diff --git a/293/_static/bg2.jpg b/293/_static/bg2.jpg
new file mode 100644
index 0000000000..fdfc5eaa8d
Binary files /dev/null and b/293/_static/bg2.jpg differ
diff --git a/293/_static/blast.png b/293/_static/blast.png
new file mode 100644
index 0000000000..85dc642982
Binary files /dev/null and b/293/_static/blast.png differ
diff --git a/293/_static/bootstrap-sphinx.css b/293/_static/bootstrap-sphinx.css
new file mode 100644
index 0000000000..1477d77c7f
--- /dev/null
+++ b/293/_static/bootstrap-sphinx.css
@@ -0,0 +1,42 @@
+/*
+* bootstrap-sphinx.css
+* ~~~~~~~~~~~~~~~~~~~~
+*
+* Sphinx stylesheet -- Twitter Bootstrap theme.
+*/
+
+.navbar-inverse .brand {
+  color: #FFF;
+}
+
+.page-top {
+  top: 0px;
+}
+
+
+body {
+
+  padding-top: 40px;
+
+}
+.page-top {
+
+  top: 40px;
+
+}
+
+.navbar-inner {
+  padding-left:  12px !important;
+  padding-right: 12px !important;
+}
+
+
+table {
+  border: 0;
+}
+
+.footer {
+  width: 100%;
+  border-top: 1px solid #ccc;
+  padding-top: 10px;
+}
\ No newline at end of file
diff --git a/293/_static/bootstrap-sphinx.js b/293/_static/bootstrap-sphinx.js
new file mode 100644
index 0000000000..5323140326
--- /dev/null
+++ b/293/_static/bootstrap-sphinx.js
@@ -0,0 +1,132 @@
+(function ($) {
+  /**
+   * Patch TOC list.
+   *
+   * Will mutate the underlying span to have a correct ul for nav.
+   *
+   * @param $span: Span containing nested UL's to mutate.
+   * @param minLevel: Starting level for nested lists. (1: global, 2: local).
+   */
+  var patchToc = function ($ul, minLevel) {
+    var findA,
+      patchTables,
+      $localLi;
+
+    // Find all a "internal" tags, traversing recursively.
+    findA = function ($elem, level) {
+      level = level || 0;
+      var $items = $elem.find("> li > a.internal, > ul, > li > ul");
+
+      // Iterate everything in order.
+      $items.each(function (index, item) {
+        var $item = $(item),
+          tag = item.tagName.toLowerCase(),
+          $childrenLi = $item.children('li'),
+          $parentLi = $($item.parent('li'), $item.parent().parent('li'));
+
+        // Add dropdowns if more children and above minimum level.
+        if (tag === 'ul' && level >= minLevel && $childrenLi.length > 0) {
+          $parentLi
+            .addClass('dropdown-submenu')
+            .children('a').first().attr('tabindex', -1);
+
+          $item.addClass('dropdown-menu');
+        }
+
+        findA($item, level + 1);
+      });
+    };
+
+    findA($ul);
+  };
+
+  /**
+   * Patch all tables to remove ``docutils`` class and add Bootstrap base
+   * ``table`` class.
+   */
+  patchTables = function () {
+    $("table.docutils")
+      .removeClass("docutils")
+      .addClass("table")
+      .attr("border", 0);
+  };
+
+  $(document).ready(function () {
+
+    /*
+     * Scroll the window to avoid the topnav bar
+     * https://github.com/twitter/bootstrap/issues/1768
+     */
+    if ($("#navbar.navbar-fixed-top").length > 0) {
+      var navHeight = $("#navbar").height(),
+        shiftWindow = function() { scrollBy(0, -navHeight - 10); };
+
+      if (location.hash) {
+        shiftWindow();
+      }
+
+      window.addEventListener("hashchange", shiftWindow);
+    }
+
+    // Add styling, structure to TOC's.
+    $(".dropdown-menu").each(function () {
+      $(this).find("ul").each(function (index, item){
+        var $item = $(item);
+        $item.addClass('unstyled');
+      });
+    });
+
+    // Global TOC.
+    if ($("ul.globaltoc li").length) {
+      patchToc($("ul.globaltoc"), 1);
+    } else {
+      // Remove Global TOC.
+      $(".globaltoc-container").remove();
+    }
+
+    // Local TOC.
+    patchToc($("ul.localtoc"), 2);
+
+    // Mutate sub-lists (for bs-2.3.0).
+    $(".dropdown-menu ul").not(".dropdown-menu").each(function () {
+      var $ul = $(this),
+        $parent = $ul.parent(),
+        tag = $parent[0].tagName.toLowerCase(),
+        $kids = $ul.children().detach();
+
+      // Replace list with items if submenu header.
+      if (tag === "ul") {
+        $ul.replaceWith($kids);
+      } else if (tag === "li") {
+        // Insert into previous list.
+        $parent.after($kids);
+        $ul.remove();
+      }
+    });
+
+    // Add divider in page TOC.
+    $localLi = $("ul.localtoc li");
+    if ($localLi.length > 2) {
+      $localLi.first().after('
  • '); + } + + // Enable dropdown. + $('.dropdown-toggle').dropdown(); + + // Patch tables. + patchTables(); + + // Add Note, Warning styles. + $('div.note').addClass('alert').addClass('alert-info'); + $('div.warning').addClass('alert').addClass('alert-warning'); + + // Inline code styles to Bootstrap style. + $('tt.docutils.literal').not(".xref").each(function (i, e) { + // ignore references + if (!$(e).parent().hasClass("reference")) { + $(e).replaceWith(function () { + return $("").text($(this).text()); + }); + }}); + }); +}(window.jQuery)); diff --git a/293/_static/bullet.png b/293/_static/bullet.png new file mode 100644 index 0000000000..327fba5a8e Binary files /dev/null and b/293/_static/bullet.png differ diff --git a/293/_static/clock.png b/293/_static/clock.png new file mode 100644 index 0000000000..9f7e4ade1a Binary files /dev/null and b/293/_static/clock.png differ diff --git a/293/_static/close.png b/293/_static/close.png new file mode 100644 index 0000000000..3ee38ebc75 Binary files /dev/null and b/293/_static/close.png differ diff --git a/293/_static/codelens.js b/293/_static/codelens.js new file mode 100644 index 0000000000..494571c027 --- /dev/null +++ b/293/_static/codelens.js @@ -0,0 +1,83 @@ +/** + * Created by bmiller on 5/10/15. + */ + +/* + Since I don't want to modify the codelens code I'll attach the logging functionality this way. + This actually seems like a better way to do it maybe across the board to separate logging + from the real funcionality. It would also allow a better way of turning off/on logging.. + As long as Philip doesn't go and change the id values for the buttons and slider this will + continue to work.... In the best of all worlds we might add a function to the visualizer to + return the buttons, but I'm having a hard time thinking of any other use for that besides mine. + */ + +import RunestoneBase from "../../common/js/runestonebase.js"; +import "./pytutor-embed.bundle.js"; +import "./../css/pytutor.css"; + +function attachLoggers(codelens, divid) { + let rb = new RunestoneBase(); + codelens.domRoot.find("#jmpFirstInstr").click(function () { + rb.logBookEvent({ event: "codelens", act: "first", div_id: divid }); + }); + codelens.domRoot.find("#jmpLastInstr").click(function () { + rb.logBookEvent({ event: "codelens", act: "last", div_id: divid }); + }); + codelens.domRoot.find("#jmpStepBack").click(function () { + rb.logBookEvent({ event: "codelens", act: "back", div_id: divid }); + }); + codelens.domRoot.find("#jmpStepFwd").click(function () { + rb.logBookEvent({ event: "codelens", act: "fwd", div_id: divid }); + }); + codelens.domRoot.find("#executionSlider").bind("slide", function (evt, ui) { + rb.logBookEvent({ event: "codelens", act: "slide", div_id: divid }); + }); + // TODO: The component isn't quite fully initialized, but it also doesn't inherit from RunestoneBase. This is a convenient place to mark it ready for now, but it should be moved forward in time during a rewrite. + rb.containerDiv = document.getElementById(divid); + rb.indicate_component_ready(); +} + +function styleButtons(divid) { + var myVis = $("#" + divid); + $(myVis).find("#jmpFirstInstr").addClass("btn btn-default"); + $(myVis).find("#jmpStepBack").addClass("btn btn-danger"); + $(myVis).find("#jmpStepFwd").addClass("btn btn-success"); + $(myVis).find("#jmpLastInstr").addClass("btn btn-default"); +} + +if (typeof allVsualizers === "undefined") { + window.allVisualizers = []; +} + +$(document).ready(function () { + if (typeof allTraceData !== "undefined") { + for (let divid in allTraceData) { + let cl = document.getElementById(divid); + let lang = $(cl).data("params").lang; + try { + let vis = addVisualizerToPage(allTraceData[divid], divid, { + startingInstruction: 0, + editCodeBaseURL: null, + hideCode: false, + lang: lang, + }); + attachLoggers(vis, divid); + styleButtons(divid); + window.allVisualizers.push(vis); + } catch (err) { + console.log(`Error rendering CodeLens Problem ${divid}`); + console.log(err); + } + } + document.addEventListener("codelens:answer", function (evt) { + let rb = new RunestoneBase(); + rb.logBookEvent({ + event: "codelens", + div_id: evt.detail.divid, + act: `answer:${evt.detail.answer}`, + correct: evt.detail.correct, + }); + console.log(evt); + }); + } +}); diff --git a/293/_static/dest.png b/293/_static/dest.png new file mode 100644 index 0000000000..4a7684610e Binary files /dev/null and b/293/_static/dest.png differ diff --git a/293/_static/doctools.js b/293/_static/doctools.js new file mode 100644 index 0000000000..61ac9d266f --- /dev/null +++ b/293/_static/doctools.js @@ -0,0 +1,321 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('
    \u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/293/_static/documentation_options.js b/293/_static/documentation_options.js new file mode 100644 index 0000000000..52dd588aee --- /dev/null +++ b/293/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '9032fd1dbbd029900c84c95f684260a77fc85c34-main', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/293/_static/docutils.css b/293/_static/docutils.css new file mode 100644 index 0000000000..7dc774da4f --- /dev/null +++ b/293/_static/docutils.css @@ -0,0 +1,215 @@ +/* ************************************ + |docname| - Style sheet for docutils + ************************************ + This style sheet provides a nicer look than Docutils' default style sheet. It's not intended for use with Sphinx, whose styles are much better. + + This file was copied from `PyInstaller `_. + */ + +body { + font-family: Verdana, Arial, sans-serif; + font-size: 10pt; + background-color: white; +} + +tt, span.literal { + font-family: monospace; + font-size: 0.95em; + background-color: #ECF0F3; + padding: 0 1px; +} + +div.document { + padding-left: 1em; + padding-right: 1em; + /** padding: 0 20px 30px; this overrides the prior 2 lines */ +} +dl, table { + margin-left: 2em; + margin-right: 2em; +} + +h1, h2, h3, h4, h5, h6 { + background-color: #F2F2F2; + border-bottom: 1px solid #CCCCCC; + color: #20435C !important; + font-family: 'Trebuchet MS',sans-serif; + font-weight: normal; + margin: 20px -20px 10px; + padding: 3px 0 3px 10px; +} + +h1 { + text-align: center; + font-variant: small-caps; +} +div#contents p.topic-title.first { + font-size: large; + font-family: 'Trebuchet MS',sans-serif; + font-weight: normal; +} +div.contents { + float:left; + margin-left: -1em; + width: 35%; + background: white; + margin-right: 2em; + padding-right: 0.5em; + border: 1px solid black; + } +a:link, a:visited { color: #006699; } +a:hover { background-color:#006699; color:white; } + +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, +h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, +h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited { + text-decoration: inherit; + background-color: inherit; + color:inherit; +} +h2 a:hover::after, h3 a:hover::after { + color: red; + content: " back to contents"; + text-decoration: unterline; + font-size: x-small; + margin-left: 1em; +} + +table.docutils { + border: 0 solid #DDCCEE; + border-collapse: collapse; +} +table.docutils td, table.docutils th { + background-color: #EEEEFF; + border-left: 0 none; + padding: 2px 5px; +} +table.docutils td p.last, table.docutils th p.last { + margin-bottom: 0; +} +table.field-list td, table.field-list th { + border: 0 none !important; +} +table.footnote td, table.footnote th { + border: 0 none !important; +} +table.docutils th { + background-color: #EEDDEE; + border-top: 1px solid #CCAACC; +} + +table.docinfo { + border: 0 solid black; + border-collapse: collapse; +} +table.docinfo th { + background-color: #EEDDEE; + border: solid thin #CCAACC; + border-top: 0; + border-left: 0; + padding: 2px 5px; +} +table.docinfo td { + background-color: #EEEEFF; + border: solid thin #EEDDFF; + border-width: 0 0 thin; + padding: 2px 5px; +} + + +table.option-list td.option-group { + padding-left: 0; + background-color: #EEDDEE; +} +table.option-list td.option-group[colspan="2"] { + background-color: #EEEEFF; +} +table.option-list td + td { + padding-bottom: 0.5em; +} +table.option-list kbd { + padding: 3px; + background-color: #EEDDEE; + white-space: nowrap; +} + +th { + padding-right: 5px; + text-align: left; + background: #FFD596; + font-weight: bold; +} +th.head { + text-align: center; +} + +td { + background: white; + text-align: left; +} + + +dl { + margin-bottom: 15px; +} + +dt { + white-space: nowrap; + font-weight: bold; +} + +pre { + background-color: #EEFFCC; + border-color: #AACC99; + border-style: solid none; + border-width: 1px medium; + color: #333333; + line-height: 120%; + padding: 0.5em; + /* margin-left: 4em; */ + margin-right: 4em; + font-family: monospace; + font-size: 0.95em; +} + +/*--- sidebar --- */ + +div.sidebar { + margin-left: 1em; + margin-bottom: 1em; + font-size: smaller; + border: medium outset; + padding: 0.5em 1em; /* needed by IE */ + background-color: #ffffee; + width: 35%; + float: right; + clear: right; +} + +p.sidebar-title { + font-weight: bold; + font-size: larger; + color: #006699; + font-variant: small-caps; +} + +div.note { + border: solid thin black; + background-color: #ffffee; + width: 90%; + padding: 0 0.5em; +} + +div.note p.admonition-title { + font-weight: bold; + float: left; + margin-right: 1em; +} + +div.note p.admonition-title:after { + content: ": " +} + +/* + * END OF FILE + */ diff --git a/293/_static/file.png b/293/_static/file.png new file mode 100644 index 0000000000..a858a410e4 Binary files /dev/null and b/293/_static/file.png differ diff --git a/293/_static/first.png b/293/_static/first.png new file mode 100644 index 0000000000..7e05c20b1e Binary files /dev/null and b/293/_static/first.png differ diff --git a/293/_static/game.js b/293/_static/game.js new file mode 100644 index 0000000000..027190c953 --- /dev/null +++ b/293/_static/game.js @@ -0,0 +1,24091 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find0 module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= rect.left) && (this.left < rect.right)) { + x = this.left; + } else if ((rect.left >= this.left) && (rect.left < this.right)) { + x = rect.left; + } + + // Right + if ((this.right > rect.left) && (this.right <= rect.right)) { + width = this.right - x; + } else if ((rect.right > this.left) && (rect.right <= this.right)) { + width = rect.right - x; + } + + // Top + if ((this.top >= rect.top) && (this.top < rect.bottom)) { + y = this.top; + } else if ((rect.top >= this.top) && (rect.top < this.bottom)) { + y = rect.top; + } + + // Bottom + if ((this.bottom > rect.top) && (this.bottom <= rect.bottom)) { + height = this.bottom - y; + } else if ((rect.bottom > this.top) && (rect.bottom <= this.bottom)) { + height = rect.bottom - y; + } + return new Rect(x, y, width, height); +}; + +/** + * Join two rectangles + * + * @param {gamejs.Rect} union with this rectangle + * @returns {gamejs.Rect} rectangle containing area of both rectangles + */ +Rect.prototype.union = function(rect) { + var x, y, width, height; + + x = Math.min(this.left, rect.left); + y = Math.min(this.top, rect.top); + width = Math.max(this.right, rect.right) - x; + height = Math.max(this.bottom, rect.bottom) - y; + return new Rect(x, y, width, height); +}; + +/** + * Grow or shrink the rectangle size + * + * @param {Number} amount to change in the width + * @param {Number} amount to change in the height + * @returns {gamejs.Rect} inflated rectangle centered on the original rectangle's center + */ +Rect.prototype.inflate = function(x, y) { + var copy = this.clone(); + + copy.inflateIp(x, y); + + return copy; +}; + +/** + * Grow or shrink this Rect in place - not returning a new Rect like `inflate(x, y)` would. + * + * @param {Number} amount to change in the width + * @param {Number} amount to change in the height + */ +Rect.prototype.inflateIp = function(x, y) { + // Use Math.floor here to deal with rounding of negative numbers the + // way this relies on. + this.left -= Math.floor(x / 2); + this.top -= Math.floor(y / 2); + this.width += x; + this.height += y; +}; + +/** + * Check for collision with a point. + * + * `collidePoint(x,y)` or `collidePoint([x,y])` or `collidePoint(new Rect(x,y))` + * + * @param {Array|gamejs.Rect} point the x and y coordinates of the point to test for collision + * @returns {Boolean} true if the point collides with this Rect + */ +Rect.prototype.collidePoint = function() { + var args = normalizeRectArguments.apply(this, arguments); + return (this.left <= args.left && args.left <= this.right) && + (this.top <= args.top && args.top <= this.bottom); +}; + +/** + * Check for collision with a Rect. + * @param {gamejs.Rect} rect the Rect to test check for collision + * @returns {Boolean} true if the given Rect collides with this Rect + */ +Rect.prototype.collideRect = function(rect) { + return !(this.left > rect.right || this.right < rect.left || + this.top > rect.bottom || this.bottom < rect.top); +}; + +/** + * @param {Array} pointA start point of the line + * @param {Array} pointB end point of the line + * @returns true if the line intersects with the rectangle + * @see http://stackoverflow.com/questions/99353/how-to-test-if-a-line-segment-intersects-an-axis-aligned-rectange-in-2d/293052#293052 + * + */ +Rect.prototype.collideLine = function(p1, p2) { + var x1 = p1[0]; + var y1 = p1[1]; + var x2 = p2[0]; + var y2 = p2[1]; + + function linePosition(point) { + var x = point[0]; + var y = point[1]; + return (y2 - y1) * x + (x1 - x2) * y + (x2 * y1 - x1 * y2); + } + + var relPoses = [[this.left, this.top], + [this.left, this.bottom], + [this.right, this.top], + [this.right, this.bottom] + ].map(linePosition); + + var noNegative = true; + var noPositive = true; + var noZero = true; + relPoses.forEach(function(relPos) { + if (relPos > 0) { + noPositive = false; + } else if (relPos < 0) { + noNegative = false; + } else if (relPos === 0) { + noZero = false; + } + }, this); + + if ( (noNegative || noPositive) && noZero) { + return false; + } + return !((x1 > this.right && x2 > this.right) || + (x1 < this.left && x2 < this.left) || + (y1 < this.top && y2 < this.top) || + (y1 > this.bottom && y2 > this.bottom) + ); +}; + +/** + * @returns {String} Like "[x, y][w, h]" + */ +Rect.prototype.toString = function() { + return ["[", this.left, ",", this.top, "]"," [",this.width, ",", this.height, "]"].join(""); +}; + +/** + * @returns {gamejs.Rect} A new copy of this rect + */ +Rect.prototype.clone = function() { + return new Rect(this); +}; + +// adapted from pygame/src/rect.c [rect_clamp()] +Rect.prototype.clamp = function(rect) { + var x = 0, y = 0; + if (this.width >= rect.width) { + x = this.x + rect.width / 2 - this.width / 2; + } else if (this.x < rect.x) { + x = rect.x; + } else if ((this.x + this.width) > (rect.x + rect.width)) { + x = rect.x + rect.width - this.width; + } else { + x = this.x; + } + + if (this.height >= rect.height) { + y = rect.y + rect.height / 2 - this.height / 2; + } else if (this.y < rect.y) { + y = rect.y; + } else if ((this.y + this.height) > (rect.y + rect.height)) { + y = rect.y + rect.height + self.height; + } else { + y = this.y; + } + + return new Rect(x, y, this.width, this.height); +}; + +// adapted from pygame/src/rect.c [rect_clamp_ip()] +Rect.prototype.clampIp = function(rect) { + var x = 0, y = 0; + if (this.width >= rect.width) { + x = this.x + rect.width / 2 - this.width / 2; + } else if (this.x < rect.x) { + x = rect.x; + } else if ((this.x + this.width) > (rect.x + rect.width)) { + x = rect.x + rect.width - this.width; + } else { + x = this.x; + } + + if (this.height >= rect.height) { + y = rect.y + rect.height / 2 - this.height / 2; + } else if (this.y < rect.y) { + y = rect.y; + } else if ((this.y + this.height) > (rect.y + rect.height)) { + y = rect.y + rect.height + self.height; + } else { + y = this.y; + } + + this.x = x; + this.y = y; +}; + +// adapted from pygame/src/rect.c [rect_fit()] +Rect.prototype.fit = function (rect) { + var w = 0, h = 0, x = 0, y = 0, xratio = 0, yratio = 0, maxratio = 0; + + xratio = this.width / rect.width; + yratio = this.height / rect.height; + maxratio = (xratio > yratio) ? xratio : yratio; + + w = this.width / maxratio; + h = this.height / maxratio; + + x = rect.x + (rect.width - w) / 2; + y = rect.y + (rect.height - h) / 2; + + return new Rect(x, y, w, h); +}; + +// adapted from pygame/src/rect.c [rect_normalize()] +Rect.prototype.normalize = function () { + if (this.width < 0) { + this.x += this.width; + this.width = -this.width; + } + + if (this.height < 0) { + this.y += this.height; + this.height = -this.height; + } +}; + +// adapted from pygame/src/rect.c [rect_contains()] +Rect.prototype.contains = function (rect) { + return ((this.x <= rect.x) && (this.y <= rect.y) && + ((this.x + this.width) >= (rect.x + rect.width)) && + ((this.y + this.height) >= (rect.y + rect.height)) && + ((this.x + this.width) > rect.x) && + ((this.y + this.height) > rect.y)); +}; + +/** + * @ignore + */ +exports.event = require('./gamejs/event'); +/** + * @ignore + */ +exports.font = require('./gamejs/font'); +/** + * @ignore + */ +exports.http = require('./gamejs/http'); +/** + * @ignore + */ +exports.image = require('./gamejs/image'); +/** + * @ignore + */ +exports.audio = require('./gamejs/audio'); +/** + * @ignore + */ +exports.graphics = require('./gamejs/graphics'); + +/** + * @ignore + */ +exports.logging = require('./gamejs/logging'); + +/** + * @ignore + */ +exports.math = { + matrix: require('./gamejs/math/matrix'), + vectors: require('./gamejs/math/vectors'), + angles: require('./gamejs/math/angles'), + binaryheap: require('./gamejs/math/binaryheap'), + random: require('./gamejs/math/random'), + noise: require('./gamejs/math/noise'), +}; + +/** + * @ignore + */ +exports.utils = { + arrays: require('./gamejs/utils/arrays'), + objects: require('./gamejs/utils/objects'), + uri: require('./gamejs/utils/uri'), + strings: require('./gamejs/utils/strings'), + xml: require('./gamejs/utils/xml'), + base64: require('./gamejs/utils/base64') +}; +/** + * @ignore + */ +exports.display = require('./gamejs/display'); +/** + * @ignore + */ +exports.pathfinding = require('./gamejs/pathfinding'); + + +/** + * @ignore + */ +exports.tiledmap = require('./gamejs/tiledmap'); + + +/** + * @ignore + */ +exports.time = require('./gamejs/time'); + +/** + * @ignore + */ +exports.pixelcollision = require('./gamejs/pixelcollision'); + +/** + * @ignore + */ +exports.gamepad = require('./gamejs/gamepad'); + +},{"./gamejs/audio":3,"./gamejs/display":4,"./gamejs/event":5,"./gamejs/font":6,"./gamejs/gamepad":7,"./gamejs/graphics":8,"./gamejs/http":9,"./gamejs/image":10,"./gamejs/logging":14,"./gamejs/math/angles":15,"./gamejs/math/binaryheap":16,"./gamejs/math/matrix":17,"./gamejs/math/noise":18,"./gamejs/math/random":19,"./gamejs/math/vectors":20,"./gamejs/pathfinding":21,"./gamejs/pixelcollision":22,"./gamejs/thread":23,"./gamejs/tiledmap":24,"./gamejs/time":25,"./gamejs/utils/arrays":26,"./gamejs/utils/base64":27,"./gamejs/utils/callback":28,"./gamejs/utils/objects":29,"./gamejs/utils/strings":30,"./gamejs/utils/uri":31,"./gamejs/utils/xml":32}],3:[function(require,module,exports){ +var gamejs = require('../gamejs'); +var howler = require('./lib/howler.core'); + +exports.Howl = howler.Howl; +exports.Howler = howler.Howler; + +/** + * @fileoverview Playing sounds with the html5 audio tag. Audio files must be preloaded + * with the usual `gamejs.preload()` function. Ogg, wav and webm supported. + * + */ + +var CACHE = {}; + +/** + * need to export preloading status for require + * @ignore + */ +var _PRELOADING = false; + +/** + * @ignore + */ +var NUM_CHANNELS = 8; + +/** + * Sets the number of available channels for the mixer. The default value is 8. + */ +exports.setNumChannels = function(count) { + NUM_CHANNELS = parseInt(count, 10) || NUM_CHANNELS; +}; + +exports.getNumChannels = function() { + return NUM_CHANNELS; +}; + +/** + * put all audios on page in cache + * if same domain as current page, remove common href-prefix + * @ignore + */ +exports.init = function() { + var audios = Array.prototype.slice.call(document.getElementsByTagName("audio"), 0); + addToCache(audios); + return; +}; + +exports.clearCache = function() { + CACHE = {}; +} + +/** + * Preload the audios into cache + * @param {String[]} List of audio URIs to load + * @returns {Function} which returns 0-1 for preload progress + * @ignore + */ +exports.preload = function(audioUrls, showProgressOrImage) { + var countTotal = 0; + var countLoaded = 0; + + function incrementLoaded() { + countLoaded++; + if (countLoaded == countTotal) { + _PRELOADING = false; + } + } + + function getProgress() { + return countTotal > 0 ? countLoaded / countTotal : 1; + } + + function successHandler() { + addToCache(this); + incrementLoaded(); + } + function errorHandler() { + incrementLoaded(); + throw new Error('Error loading ' + this.src); + } + + for (var key in audioUrls) { + if (key.indexOf('wav') == -1 && key.indexOf('ogg') == -1 && key.indexOf('webm') == -1) { + continue; + } + countTotal++; + var audio = new Audio(); + audio.addEventListener('canplay', successHandler, true); + audio.addEventListener('error', errorHandler, true); + audio.src = audioUrls[key]; + audio.gamejsKey = key; + audio.load(); + } + if (countTotal > 0) { + _PRELOADING = true; + } + return getProgress; +}; + +/** + * @ignore + */ +exports.isPreloading = function() { + return _PRELOADING; +}; + +/** + * @param {dom.ImgElement} audios the