SlideShare a Scribd company logo
1 of 28
Download to read offline
Εισαγωγή στο TDD
Test Driven
Development
Δομημένος Προγραμματισμός
Τσαγκατάκης Ιωάννης
2
Πως λύνουμε ένα πρόβλημα ;
Σχεδιασμός
Αλγορίθμου
Κώδικας
(υλοποίηση)
Profit !
3
Άσκηση 4
Γράψτε ένα πρόγραμμα το οποίο θα βρίσκει και θα εμφανίζει στη
οθόνη όλους τους τετραψήφιους αριθμούς που είναι ίσοι με το
άθροισμα των ψηφίων τους στη τέταρτη δύναμη.
Α Β C D
0...9
1...9
Ένα κόμμα κάνει την διαφορά
#include <math.h>
int a, b, c, d, x;
int sum1 = pow(a, 4) + pow(b, 4) +
pow(c, 4) + pow(d, 4);
int sum2 = pow(a + b + c + d, 4);
4
undefined reference to `pow'
●
Χρειάζεται την βιβλιοθήκη libm
gcc -Wall -Wconversion -o ex4 -lm ex4.c
●
cmake
cmake_minimum_required(VERSION 3.15 )
project(Ergasia1 C)
add_compile_options(-Wall -Wextra -Wconversion -Wpedantic)
add_executable(ex1 ex1.c)
add_executable(ex4 ex4.c)
target_link_libraries(ex4 m)
5
undefined reference to `pow'
●
Περιφραστικά
●
Συνάρτηση
int sum3= a*a*a*a + b*b*b*b + c*c*c*c + d*d*d*d;
int pow4(int num) {
int result = num * num * num * num;
return result;
}
6
Μια απλή λύση
int main() {
for (int a = 1; a <= 9; a++) {
for (int b = 0; b <= 9; b++) {
for (int c = 0; c <= 9; c++) {
for (int d = 0; d <= 9; d++) {
// Horner method
int x = (((a * 10) + b) * 10 + c) * 10 + d;
int sum = pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4);
if (sum == x) {
printf("Solution found %dn", x);
}
}
}
}
}
}
Solution found 1634
Solution found 8208
Solution found 9474
Είναι σωστά;
7
Μια (αυστηρή) κριτική της λύσης
●
Δουλεύει μόνο για 4ψήφιους αριθμούς
– Αν αύριο μας ζητήσουν για 5-ψήφιους αριθμούς;
●
Κάνει πολλά πράγματα μπλεγμένα μεταξύ τους
– Παραγωγή 4-ψήφιων αριθμών
– Έλεγχος της συνθήκης φιλτραρίσματος. Αν αύριο αλλάξει;
●
Πάντα αναζητούμε ποιο γενικές λύσεις
●
Αυτά δεν είναι προβλήματα στο επίπεδο που είμαστε,
αλλά καλό να το έχουμε υπόψιν μας
8
Μια συνήθης λύση
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
int main() {
bool isFound = false;
int a, b, c, d;
for (int x = 1000; x <= 9999; x++) {
a = 0;
b = 0;
c = 0;
d = 0;
int sum = pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4);
if (sum == x) {
printf("Solution found %dn", x);
isFound = true;
}
}
if (isFound == false) {
puts("No solutions found");
}
}
9
Ο λογικός τύπος bool
// Old C
typedef int bool;
#define true 1
#define false 0
// C99
#include <stdbool.h>
10
Μια συνήθης λύση
(μικρά προβλήματα)
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
int main() {
bool isFound = false;
int a, b, c, d;
for (int x = 1000; x <= 9999; x++) {
a = 0;
b = 0;
c = 0;
d = 0;
double sum = pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4);
if (sum == x) {
printf("Solution found %dn", x);
isFound = true;
}
}
if (isFound == false) {
puts("No solutions found");
}
}
warning: conversion to ‘int’ from ‘double’ may
alter its value [-Wfloat-conversion]
Αυτά θέλουν σκέψη,
ας το καθυστερήσουμε λιγάκι
Έτσι θα ξέρω και πως αυτό θα δουλέψει !
11
Test Driven Development
●
Σπάω το πρόβλημα
σε μικρότερα και
απλούστερα
●
Βεβαιώνομε πως
κάθε τι είναι σωστό
●
Ο αλγόριθμος θα
προκύψει
12
Τα assertions
●
Το TDD του φτωχού
●
Μια συνθήκη που αν δεν είναι αληθής
– Σε Release mode δεν υπάρχουν
●
δεν θα κάνουν τίποτα, ούτε θα παραχθεί κώδικας
– Σε Debug mode
●
Θα σταματήσουν βίαια την εκτέλεση του προγράμματος
●
Με ένα Debugger θα δούμε την λάθος τιμή.
13
Εισαγωγή στα assertions
#include <assert.h>
int main() {
int x = 4712;
int a, b, c, d;
a = 0;
b = 0;
c = 0;
d = 0;
assert(a == 4);
assert(b == 7);
assert(c == 1);
assert(d == 2);
puts("All assertions passed !");
}
main: Assertion `a == 4' failed.
Ας το φτιάξουμε
14
Εισαγωγή στα assertions
#include <assert.h>
int main() {
int x = 4712;
int a, b, c, d;
a = 4;
b = 7;
c = 1;
d = 2;
assert(a == 4);
assert(b == 7);
assert(c == 1);
assert(d == 2);
puts("All assertions passed !");
}
Ας το φτιάξουμε
στα αλήθεια
15
Βήμα 2: Assertion pass
●
Ο κώδικας δουλεύει
●
Υπάρχει κάποια κρυμμένη δομή;
●
Μπορεί να γίνει ποιο γενικός;
int x = 4712;
int d = x % 10;
int a = x / 1000;
int b = (x / 100) % 10;
int c = (x / 10) % 10;
assert(a == 4);
assert(b == 7);
assert(c == 1);
assert(d == 2); int a = x / 1000; // 3
int b = (x / 100) % 10; // 2
int c = (x / 10) % 10; // 1
int d = x % 10; // 0
16
Αναζητώντας ένα γενικό τύπο
●
Ο κώδικας δουλεύει
●
Υπάρχει κάποια κρυμμένη δομή;
●
Μπορεί να γίνει ποιο γενικός;
int a = x / 1000; // 3
int b = (x / 100) % 10; // 2
int c = (x / 10) % 10; // 1
int d = x % 10; // 0
// 1st pass
int a = (x / 1000) % 10; // 3
int b = (x / 100) % 10; // 2
int c = (x / 10) % 10; // 1
int d = (x / 1) % 10; // 0
// 2nd pass
int a = (x / 10^3) % 10; // 3
int b = (x / 10^2) % 10; // 2
int c = (x / 10^1) % 10; // 1
int d = (x / 10^0) % 10; // 0
17
Βήμα 3 : Refactoring
int ipow(int num, int to) {
double result = pow(num, to);
return (int)result;
}
int main() {
int x = 4712;
int a = (x / ipow(10, 3)) % 10; // 3
int b = (x / ipow(10, 2)) % 10; // 2
int c = (x / ipow(10, 1)) % 10; // 1
int d = (x / ipow(10, 0)) % 10; // 0
assert(a == 4); assert(b == 7);
assert(c == 1); assert(d == 2);
int sum = ipow(a, 4) + ipow(b, 4) + ipow(c, 4) + ipow(d, 4);
assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674
puts("All assertions passed !");
}
18
Βήμα 3.1 : Refactoring with for
int ipow(int num, int to) {
double result = pow(num, to);
return (int)result;
}
int main() {
int x = 4712;
int digits = 4;
int sum = 0;
for(int i=0; i< digits; i++) {
int digit = (x / ipow(10, i)) % 10;
sum = sum + ipow(digit,4);
}
assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674
puts("All assertions passed !");
}
19
Βήμα 3.2 : Refactoring no doubles
int ipow(int num, int to) {
int result = 1;
for (int i = 0; i < to; i++)
result *= num;
return result;
}
int main() {
int x = 4712;
int digits = 4;
int sum = 0;
for(int i=0; i< digits; i++) {
int digit = (x / ipow(10, i)) % 10;
sum += ipow(digit,4);
}
assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674
puts("All assertions passed !");
}
20
Βήμα 3.3
int ipow(int num, int to) {
int result = 1;
for (int i = 0; i < to; i++)
result *= num;
return result;
}
int main() {
int x = 4712;
int digits = 4;
int sum = 0;
for(int i=0; i< digits; i++) {
int digit = (x / ipow(10, i)) % 10;
sum += ipow(digit,4);
}
assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674
puts("All assertions passed !");
}
Χωρίς
αυτό;
21
Βήμα 3.3 : Refactoring do..while
int main() {
int x = 4712;
...
int sum2 = 0;
int num = x;
do {
int digit = num % 10;
sum2 = sum2 + ipow(digit, 4);
num = num / 10;
} while ( num != 0 );
assert(sum2==sum);
...
}
ΟΚ
22
Βήμα 3.4
int main() {
int x = 4712;
...
int sum2 = 0;
int num = x;
do {
int digit = num % 10;
sum2 = sum2 + ipow(digit, 4);
num = num / 10;
} while ( num != 0 );
assert(sum2==sum);
...
}
Συνάρτηση;
23
Βήμα 3.4 : Refactoring to functions
int ipow(int num, int to);
int calculateSquare4(int num);
int calculateSquare4(int num) {
int sum = 0;
do {
int digit = num % 10;
sum += ipow(digit, 4);
num = num / 10;
} while ( num != 0 );
return sum;
}
int main() {
int x = 4712;
int sum = calculateSquare4(x);
assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674
puts("All assertions passed !");
}
24
Βήμα 3.5 : Βελτιστοποιώντας την ipow
●
Εφόσον τα πάντα είναι στην θέση τους μπορώ
να κάνω με ασφάλεια μικρές πινελιές απόδοσης
int ipow4(int num);
int ipow4(int num) {
int temp = num * num;
return temp *temp;
}
25
Το τελικό πρόγραμμα
int main() {
bool isFound = false;
for (int x = 1000; x <= 9999; x++) {
int sum = calculateSquare4(x);
if (sum == x) {
printf("A solution found %dn", x);
isFound = true;
}
}
if (isFound == false) {
puts("No solutions found");
}
}
26
Συμπεράσματα
●
Καταλήξαμε (σχεδόν αυτόματα!) σε ένα κομψό αλγόριθμο
●
Εύκολα κατανοητός και με ευκολία αλλαγής
– Τα assertions μας προστάτευαν από τα λάθη μας
– Πόσο εύκολα αλλάζει αν κάναμε λάθος στο “,” της εκφώνησης;
●
Ποιο γενικός κώδικας
– Δουλεύει με αριθμούς οποιουδήποτε μεγέθους.
– Δεν χρησιμοποιεί αριθμούς κινητής υποδιαστολής
27
Μικροβελτιστοποιήσεις
●
Μια μοντέρνα CPU είναι πολύπλοκη.
●
Δεν είναι όλες οι πράξεις ίδιες.
●
Δεν είναι όλες οι προσβάσεις στην μνήμη ίδιες
●
Η κλίμακα είναι λογαριθμική
●
Η πρόσβαση στην μνήμη συχνά ποιο σημαντική
από τον αλγόριθμο
●
Μια απλή αλλαγή μπορεί να αλλάξει την ταχύτητα
Χ100 φορές.
●
Μόνο με μετρήσεις μπορούμε να ξτο
τεκμηριώσουμε,
●
Δεν θα ασχοληθούμε με αυτό περαιτέρω
28
Ήταν δύσκολο;
“Πονάει πάντα η πρώτη φορά”
Γιάννης Αγγελάκας, Τρύπες

More Related Content

More from jtsagata

Advanced Notes on Pointers
Advanced Notes on PointersAdvanced Notes on Pointers
Advanced Notes on Pointersjtsagata
 
GPGPU Computation
GPGPU ComputationGPGPU Computation
GPGPU Computationjtsagata
 
Linux and C
Linux and CLinux and C
Linux and Cjtsagata
 
Greek utf8
Greek utf8Greek utf8
Greek utf8jtsagata
 
Function pointers in C
Function pointers in CFunction pointers in C
Function pointers in Cjtsagata
 
Why computers can' compute
Why computers can' computeWhy computers can' compute
Why computers can' computejtsagata
 
Τι είναι υπολογισμός
Τι είναι υπολογισμόςΤι είναι υπολογισμός
Τι είναι υπολογισμόςjtsagata
 
IEEE 754 Floating point
IEEE 754 Floating pointIEEE 754 Floating point
IEEE 754 Floating pointjtsagata
 
Η Τέχνη του TeX/LaTeX
Η Τέχνη του TeX/LaTeXΗ Τέχνη του TeX/LaTeX
Η Τέχνη του TeX/LaTeXjtsagata
 
Unikernels
UnikernelsUnikernels
Unikernelsjtsagata
 
FPGA on the Cloud
FPGA on the Cloud FPGA on the Cloud
FPGA on the Cloud jtsagata
 
Evolutionary keyboard Layout
Evolutionary keyboard LayoutEvolutionary keyboard Layout
Evolutionary keyboard Layoutjtsagata
 
Το εργαλείο
Το εργαλείοΤο εργαλείο
Το εργαλείοjtsagata
 

More from jtsagata (16)

Advanced Notes on Pointers
Advanced Notes on PointersAdvanced Notes on Pointers
Advanced Notes on Pointers
 
C locales
C localesC locales
C locales
 
GPGPU Computation
GPGPU ComputationGPGPU Computation
GPGPU Computation
 
Linux and C
Linux and CLinux and C
Linux and C
 
Git intro
Git introGit intro
Git intro
 
Greek utf8
Greek utf8Greek utf8
Greek utf8
 
Function pointers in C
Function pointers in CFunction pointers in C
Function pointers in C
 
Why computers can' compute
Why computers can' computeWhy computers can' compute
Why computers can' compute
 
Τι είναι υπολογισμός
Τι είναι υπολογισμόςΤι είναι υπολογισμός
Τι είναι υπολογισμός
 
IEEE 754 Floating point
IEEE 754 Floating pointIEEE 754 Floating point
IEEE 754 Floating point
 
Η Τέχνη του TeX/LaTeX
Η Τέχνη του TeX/LaTeXΗ Τέχνη του TeX/LaTeX
Η Τέχνη του TeX/LaTeX
 
Unikernels
UnikernelsUnikernels
Unikernels
 
FPGA on the Cloud
FPGA on the Cloud FPGA on the Cloud
FPGA on the Cloud
 
Evolutionary keyboard Layout
Evolutionary keyboard LayoutEvolutionary keyboard Layout
Evolutionary keyboard Layout
 
Omilia
OmiliaOmilia
Omilia
 
Το εργαλείο
Το εργαλείοΤο εργαλείο
Το εργαλείο
 

Eισαγωγή στο TDD

  • 1. Εισαγωγή στο TDD Test Driven Development Δομημένος Προγραμματισμός Τσαγκατάκης Ιωάννης
  • 2. 2 Πως λύνουμε ένα πρόβλημα ; Σχεδιασμός Αλγορίθμου Κώδικας (υλοποίηση) Profit !
  • 3. 3 Άσκηση 4 Γράψτε ένα πρόγραμμα το οποίο θα βρίσκει και θα εμφανίζει στη οθόνη όλους τους τετραψήφιους αριθμούς που είναι ίσοι με το άθροισμα των ψηφίων τους στη τέταρτη δύναμη. Α Β C D 0...9 1...9 Ένα κόμμα κάνει την διαφορά #include <math.h> int a, b, c, d, x; int sum1 = pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4); int sum2 = pow(a + b + c + d, 4);
  • 4. 4 undefined reference to `pow' ● Χρειάζεται την βιβλιοθήκη libm gcc -Wall -Wconversion -o ex4 -lm ex4.c ● cmake cmake_minimum_required(VERSION 3.15 ) project(Ergasia1 C) add_compile_options(-Wall -Wextra -Wconversion -Wpedantic) add_executable(ex1 ex1.c) add_executable(ex4 ex4.c) target_link_libraries(ex4 m)
  • 5. 5 undefined reference to `pow' ● Περιφραστικά ● Συνάρτηση int sum3= a*a*a*a + b*b*b*b + c*c*c*c + d*d*d*d; int pow4(int num) { int result = num * num * num * num; return result; }
  • 6. 6 Μια απλή λύση int main() { for (int a = 1; a <= 9; a++) { for (int b = 0; b <= 9; b++) { for (int c = 0; c <= 9; c++) { for (int d = 0; d <= 9; d++) { // Horner method int x = (((a * 10) + b) * 10 + c) * 10 + d; int sum = pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4); if (sum == x) { printf("Solution found %dn", x); } } } } } } Solution found 1634 Solution found 8208 Solution found 9474 Είναι σωστά;
  • 7. 7 Μια (αυστηρή) κριτική της λύσης ● Δουλεύει μόνο για 4ψήφιους αριθμούς – Αν αύριο μας ζητήσουν για 5-ψήφιους αριθμούς; ● Κάνει πολλά πράγματα μπλεγμένα μεταξύ τους – Παραγωγή 4-ψήφιων αριθμών – Έλεγχος της συνθήκης φιλτραρίσματος. Αν αύριο αλλάξει; ● Πάντα αναζητούμε ποιο γενικές λύσεις ● Αυτά δεν είναι προβλήματα στο επίπεδο που είμαστε, αλλά καλό να το έχουμε υπόψιν μας
  • 8. 8 Μια συνήθης λύση #include <math.h> #include <stdbool.h> #include <stdio.h> int main() { bool isFound = false; int a, b, c, d; for (int x = 1000; x <= 9999; x++) { a = 0; b = 0; c = 0; d = 0; int sum = pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4); if (sum == x) { printf("Solution found %dn", x); isFound = true; } } if (isFound == false) { puts("No solutions found"); } }
  • 9. 9 Ο λογικός τύπος bool // Old C typedef int bool; #define true 1 #define false 0 // C99 #include <stdbool.h>
  • 10. 10 Μια συνήθης λύση (μικρά προβλήματα) #include <math.h> #include <stdbool.h> #include <stdio.h> int main() { bool isFound = false; int a, b, c, d; for (int x = 1000; x <= 9999; x++) { a = 0; b = 0; c = 0; d = 0; double sum = pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4); if (sum == x) { printf("Solution found %dn", x); isFound = true; } } if (isFound == false) { puts("No solutions found"); } } warning: conversion to ‘int’ from ‘double’ may alter its value [-Wfloat-conversion] Αυτά θέλουν σκέψη, ας το καθυστερήσουμε λιγάκι Έτσι θα ξέρω και πως αυτό θα δουλέψει !
  • 11. 11 Test Driven Development ● Σπάω το πρόβλημα σε μικρότερα και απλούστερα ● Βεβαιώνομε πως κάθε τι είναι σωστό ● Ο αλγόριθμος θα προκύψει
  • 12. 12 Τα assertions ● Το TDD του φτωχού ● Μια συνθήκη που αν δεν είναι αληθής – Σε Release mode δεν υπάρχουν ● δεν θα κάνουν τίποτα, ούτε θα παραχθεί κώδικας – Σε Debug mode ● Θα σταματήσουν βίαια την εκτέλεση του προγράμματος ● Με ένα Debugger θα δούμε την λάθος τιμή.
  • 13. 13 Εισαγωγή στα assertions #include <assert.h> int main() { int x = 4712; int a, b, c, d; a = 0; b = 0; c = 0; d = 0; assert(a == 4); assert(b == 7); assert(c == 1); assert(d == 2); puts("All assertions passed !"); } main: Assertion `a == 4' failed. Ας το φτιάξουμε
  • 14. 14 Εισαγωγή στα assertions #include <assert.h> int main() { int x = 4712; int a, b, c, d; a = 4; b = 7; c = 1; d = 2; assert(a == 4); assert(b == 7); assert(c == 1); assert(d == 2); puts("All assertions passed !"); } Ας το φτιάξουμε στα αλήθεια
  • 15. 15 Βήμα 2: Assertion pass ● Ο κώδικας δουλεύει ● Υπάρχει κάποια κρυμμένη δομή; ● Μπορεί να γίνει ποιο γενικός; int x = 4712; int d = x % 10; int a = x / 1000; int b = (x / 100) % 10; int c = (x / 10) % 10; assert(a == 4); assert(b == 7); assert(c == 1); assert(d == 2); int a = x / 1000; // 3 int b = (x / 100) % 10; // 2 int c = (x / 10) % 10; // 1 int d = x % 10; // 0
  • 16. 16 Αναζητώντας ένα γενικό τύπο ● Ο κώδικας δουλεύει ● Υπάρχει κάποια κρυμμένη δομή; ● Μπορεί να γίνει ποιο γενικός; int a = x / 1000; // 3 int b = (x / 100) % 10; // 2 int c = (x / 10) % 10; // 1 int d = x % 10; // 0 // 1st pass int a = (x / 1000) % 10; // 3 int b = (x / 100) % 10; // 2 int c = (x / 10) % 10; // 1 int d = (x / 1) % 10; // 0 // 2nd pass int a = (x / 10^3) % 10; // 3 int b = (x / 10^2) % 10; // 2 int c = (x / 10^1) % 10; // 1 int d = (x / 10^0) % 10; // 0
  • 17. 17 Βήμα 3 : Refactoring int ipow(int num, int to) { double result = pow(num, to); return (int)result; } int main() { int x = 4712; int a = (x / ipow(10, 3)) % 10; // 3 int b = (x / ipow(10, 2)) % 10; // 2 int c = (x / ipow(10, 1)) % 10; // 1 int d = (x / ipow(10, 0)) % 10; // 0 assert(a == 4); assert(b == 7); assert(c == 1); assert(d == 2); int sum = ipow(a, 4) + ipow(b, 4) + ipow(c, 4) + ipow(d, 4); assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674 puts("All assertions passed !"); }
  • 18. 18 Βήμα 3.1 : Refactoring with for int ipow(int num, int to) { double result = pow(num, to); return (int)result; } int main() { int x = 4712; int digits = 4; int sum = 0; for(int i=0; i< digits; i++) { int digit = (x / ipow(10, i)) % 10; sum = sum + ipow(digit,4); } assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674 puts("All assertions passed !"); }
  • 19. 19 Βήμα 3.2 : Refactoring no doubles int ipow(int num, int to) { int result = 1; for (int i = 0; i < to; i++) result *= num; return result; } int main() { int x = 4712; int digits = 4; int sum = 0; for(int i=0; i< digits; i++) { int digit = (x / ipow(10, i)) % 10; sum += ipow(digit,4); } assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674 puts("All assertions passed !"); }
  • 20. 20 Βήμα 3.3 int ipow(int num, int to) { int result = 1; for (int i = 0; i < to; i++) result *= num; return result; } int main() { int x = 4712; int digits = 4; int sum = 0; for(int i=0; i< digits; i++) { int digit = (x / ipow(10, i)) % 10; sum += ipow(digit,4); } assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674 puts("All assertions passed !"); } Χωρίς αυτό;
  • 21. 21 Βήμα 3.3 : Refactoring do..while int main() { int x = 4712; ... int sum2 = 0; int num = x; do { int digit = num % 10; sum2 = sum2 + ipow(digit, 4); num = num / 10; } while ( num != 0 ); assert(sum2==sum); ... } ΟΚ
  • 22. 22 Βήμα 3.4 int main() { int x = 4712; ... int sum2 = 0; int num = x; do { int digit = num % 10; sum2 = sum2 + ipow(digit, 4); num = num / 10; } while ( num != 0 ); assert(sum2==sum); ... } Συνάρτηση;
  • 23. 23 Βήμα 3.4 : Refactoring to functions int ipow(int num, int to); int calculateSquare4(int num); int calculateSquare4(int num) { int sum = 0; do { int digit = num % 10; sum += ipow(digit, 4); num = num / 10; } while ( num != 0 ); return sum; } int main() { int x = 4712; int sum = calculateSquare4(x); assert(sum == pow(4, 4) + pow(7, 4) + pow(1, 4) + pow(2, 4)); // 2674 puts("All assertions passed !"); }
  • 24. 24 Βήμα 3.5 : Βελτιστοποιώντας την ipow ● Εφόσον τα πάντα είναι στην θέση τους μπορώ να κάνω με ασφάλεια μικρές πινελιές απόδοσης int ipow4(int num); int ipow4(int num) { int temp = num * num; return temp *temp; }
  • 25. 25 Το τελικό πρόγραμμα int main() { bool isFound = false; for (int x = 1000; x <= 9999; x++) { int sum = calculateSquare4(x); if (sum == x) { printf("A solution found %dn", x); isFound = true; } } if (isFound == false) { puts("No solutions found"); } }
  • 26. 26 Συμπεράσματα ● Καταλήξαμε (σχεδόν αυτόματα!) σε ένα κομψό αλγόριθμο ● Εύκολα κατανοητός και με ευκολία αλλαγής – Τα assertions μας προστάτευαν από τα λάθη μας – Πόσο εύκολα αλλάζει αν κάναμε λάθος στο “,” της εκφώνησης; ● Ποιο γενικός κώδικας – Δουλεύει με αριθμούς οποιουδήποτε μεγέθους. – Δεν χρησιμοποιεί αριθμούς κινητής υποδιαστολής
  • 27. 27 Μικροβελτιστοποιήσεις ● Μια μοντέρνα CPU είναι πολύπλοκη. ● Δεν είναι όλες οι πράξεις ίδιες. ● Δεν είναι όλες οι προσβάσεις στην μνήμη ίδιες ● Η κλίμακα είναι λογαριθμική ● Η πρόσβαση στην μνήμη συχνά ποιο σημαντική από τον αλγόριθμο ● Μια απλή αλλαγή μπορεί να αλλάξει την ταχύτητα Χ100 φορές. ● Μόνο με μετρήσεις μπορούμε να ξτο τεκμηριώσουμε, ● Δεν θα ασχοληθούμε με αυτό περαιτέρω
  • 28. 28 Ήταν δύσκολο; “Πονάει πάντα η πρώτη φορά” Γιάννης Αγγελάκας, Τρύπες