Exercises in Style
Crista Lopes
Available on Amazon
PROGRAMMING STYLES
Rules and constraints in software construction
Programming Styles
⊳ Ways of expressing tasks
⊳ Exist and recur at all scales
⊳ Frozen in Programming
Languages
Why Are Styles Important?
⊳ Basic frames of reference for
solutions
• Like scaffolding
⊳ Common vocabularies
• It’s a cult...
Programming Styles
How do you teach this?
Raymond Queneau
Queneau’s Exercises in Style
⊳ Metaphor
⊳ Surprises
⊳ Dream
⊳ Prognostication
⊳ Hesitation
⊳ Precision
⊳ Negativities
⊳ As...
Queneau’s “Styles”
⊳ Constraints
⊳ “A Void” (La Disparition)
by Georges Perec
• No letter ‘e’
Exercises in Programming Style
The story:
Term Frequency
given a text file,
output a list of the 25
most frequently-occurr...
Exercises in Programming Style
The story:
Term Frequency
given a text file,
output a list of the 25
most frequently-occurr...
STYLE #1
@cristalopes #style1 name
# the global list of [word, frequency] pairs
word_freqs = []
# the list of stop words
with open('../stop_words.txt') as f:...
for line in open(sys.argv[1]):
for c in line:
Style #1 Main Characteristics
⊳ No abstractions
⊳ No use of library functions
@cristalopes #style1 name
Style #1 Main Characteristics
⊳ No abstractions
⊳ No use of library functions
Brain-dump Style
@cristalopes #style1 name
STYLE #2
@cristalopes #style2 name
import re, string, sys
stops = set(open("../stop_words.txt").read().split(",") + list(string.ascii_lowercase))
words = [x....
import re, string, sys
stops = set(open("../stop_words.txt").read().split(",") +
list(string.ascii_lowercase))
words = [x....
import re, string, sys
stops = set(open("../stop_words.txt").read().split(",") +
list(string.ascii_lowercase))
words = [x....
Style #2 Main Characteristics
⊳ As few lines of code as possible
@cristalopes #style2 name
Style #2 Main Characteristics
⊳ As few lines of code as possible
Code Golf Style
@cristalopes #style2 name
Style #2 Main Characteristics
⊳ As few lines of code as possible
Try Hard Style
@cristalopes #style2 name
STYLE #3
@cristalopes #style3 name
#
# Main
#
read_file(sys.argv[1])
filter_normalize()
scan()
rem_stop_words()
frequencies()
sort()
for tf in word_freqs[0:2...
Style #3 Main Characteristics
⊳ Procedural abstractions
• maybe input, no output
⊳ Shared state
⊳ Larger problem solved by...
Style #3 Main Characteristics
⊳ Procedural abstractions
• maybe input, no output
⊳ Shared state
⊳ Commands
Cook Book Style...
STYLE #4
@cristalopes #style4 name
#
# Main
#
wfreqs=st(fq(r(sc(n(fc(rf(sys.argv[1])))))))
for tf in wfreqs[0:25]:
print tf[0], ' - ', tf[1]
def read_file(pa...
Style #4 Main Characteristics
⊳ Function abstractions
• f: Input  Output
⊳ No shared state
⊳ Function composition f º g
@...
Style #4 Main Characteristics
⊳ Function abstractions
• f: Input  Output
⊳ No shared state
⊳ Function composition f º g
C...
STYLE #5
@cristalopes #style5 name
def read_file(path, func):
...
return func(…, normalize)
def filter_chars(data, func):
...
return func(…, scan)
def normal...
Style #5 Main Characteristics
⊳ Functions take one additional
parameter, f
• called at the end
• given what would normally...
Style #5 Main Characteristics
⊳ Functions take one additional
parameter, f
• called at the end
• given what would normally...
STYLE #6
@cristalopes #style6 name
class DataStorageManager(TFExercise):
class TFExercise():
class StopWordManager(TFExercise):
class WordFreqManager(TFExerc...
Style #6 Main Characteristics
⊳ Things, things and more things!
• Capsules of data and procedures
⊳ Data is never accessed...
Style #6 Main Characteristics
⊳ Things, things and more things!
• Capsules of data and procedures
⊳ Data is never accessed...
STYLE #7
@cristalopes #style7 name
class DataStorageManager():
class StopWordManager():
class WordFrequencyManager():
class WordFrequencyController():
def di...
Style #7 Main Characteristics
⊳ (Similar to #6)
⊳ Capsules receive messages via
single receiving procedure
@cristalopes #s...
Style #7 Main Characteristics
⊳ (Similar to #6)
⊳ Capsules receive messages via
single receiving procedure
@cristalopes #s...
STYLE #8
@cristalopes #style8 name
# Main
splits = map(split_words,
partition(read_file(sys.argv[1]), 200))
splits.insert(0, [])
word_freqs = sort(reduce(cou...
def split_words(data_str)
"""
Takes a string (many lines), filters, normalizes to
lower case, scans for words, and filters...
def count_words(pairs_list_1, pairs_list_2)
"""
Takes two lists of pairs of the form
[(w1, 1), ...]
and returns a list of ...
Style #8 Main Characteristics
⊳ Two key abstractions:
map(f, chunks) and
reduce(g, results)
@cristalopes #style8 name
Style #8 Main Characteristics
⊳ Two key abstractions:
map(f, chunks) and
reduce(g, results)
@cristalopes #style8 name
Map-...
STYLE #9
@cristalopes #style9 name
# Main
connection = sqlite3.connect(':memory:')
create_db_schema(connection)
load_file_into_database(sys.argv[1], connecti...
def create_db_schema(connection):
c = connection.cursor()
c.execute('''CREATE TABLE documents(id PRIMARY KEY AUTOINCREMENT...
# Now let's add data to the database
# Add the document itself to the database
c = connection.cursor()
c.execute("INSERT I...
Style #9 Main Characteristics
⊳ Entities and relations between them
⊳ Query engine
• Declarative queries
@cristalopes #sty...
Style #9 Main Characteristics
⊳ Entities and relations between them
⊳ Query engine
• Declarative queries
@cristalopes #sty...
Take Home
⊳ Many ways of solving problems
• Know them, assess them
⊳ Constraints are important for
communication
• Make th...
Available on Amazon
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Ejercicios de estilo en la programación
Upcoming SlideShare
Loading in...5
×

Ejercicios de estilo en la programación

368

Published on

El escritor francés Raymond Queneau escribió a mediados del siglo XX un libro llamado "Ejercicios de Estilo" donde mostraba una misma historia corta, redactada de 99 formas distintas.

En esta plática realizaremos el mismo ejercicio con un programa de software. Abarcaremos distintos estilos y paradigmas: programación monolítica, orientada a objetos, relacional, orientada a aspectos, monadas, map-reduce, y muchos otros, a través de los cuales podremos apreciar la riqueza del pensamiento humano aplicado a la computación.

Esto va mucho más allá de un ejercicio académico; el diseño de sistemas de gran escala se alimenta de esta variedad de estilos. También platicaremos sobre los peligros de quedar atrapado bajo un conjunto reducido de estilos a lo largo de tu carrera, y la necesidad de verdaderamente entender distintos estilos al diseñar arquitecturas de sistemas de software.

Semblanza del conferencista:
Crista Lopez es profesora en la Facultad de Ciencias Computacionales de la Universidad de California en Irvine. Su investigación se enfoca en prácticas de ingeniería de software para sistemas de gran escala. Previamente, fue miembro fundador del equipo en Xerox PARC creador del paradigma de programación orientado a aspectos (AOP). Crista es una de las desarrolladoras principales de OpenSimulator, una plataforma open source para crear mundos virtuales 3D. También es fundadora de Encitra, empresa especializada en la utilización de la realidad virtual para proyectos de desarrollo urbano sustentable. @cristalopes

Published in: Software, Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
368
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Ejercicios de estilo en la programación

  1. 1. Exercises in Style Crista Lopes
  2. 2. Available on Amazon
  3. 3. PROGRAMMING STYLES Rules and constraints in software construction
  4. 4. Programming Styles ⊳ Ways of expressing tasks ⊳ Exist and recur at all scales ⊳ Frozen in Programming Languages
  5. 5. Why Are Styles Important? ⊳ Basic frames of reference for solutions • Like scaffolding ⊳ Common vocabularies • It’s a cultural thing ⊳ Some better than others • Depending on many things!
  6. 6. Programming Styles How do you teach this?
  7. 7. Raymond Queneau
  8. 8. Queneau’s Exercises in Style ⊳ Metaphor ⊳ Surprises ⊳ Dream ⊳ Prognostication ⊳ Hesitation ⊳ Precision ⊳ Negativities ⊳ Asides ⊳ Anagrams ⊳ Logical analysis ⊳ Past ⊳ Present ⊳ … ⊳ (99)
  9. 9. Queneau’s “Styles” ⊳ Constraints ⊳ “A Void” (La Disparition) by Georges Perec • No letter ‘e’
  10. 10. Exercises in Programming Style The story: Term Frequency given a text file, output a list of the 25 most frequently-occurring words, ordered by decreasing frequency
  11. 11. Exercises in Programming Style The story: Term Frequency given a text file, output a list of the 25 most frequently-occurring words, ordered by decreasing frequency mr - 786 elizabeth - 635 very - 488 darcy - 418 such - 395 mrs - 343 much - 329 more - 327 bennet - 323 bingley - 306 jane - 295 miss - 283 one - 275 know - 239 before - 229 herself - 227 though - 226 well - 224 never - 220 … TFPride and Prejudice
  12. 12. STYLE #1 @cristalopes #style1 name
  13. 13. # the global list of [word, frequency] pairs word_freqs = [] # the list of stop words with open('../stop_words.txt') as f: stop_words = f.read().split(',') stop_words.extend(list(string.ascii_lowercase))
  14. 14. for line in open(sys.argv[1]): for c in line:
  15. 15. Style #1 Main Characteristics ⊳ No abstractions ⊳ No use of library functions @cristalopes #style1 name
  16. 16. Style #1 Main Characteristics ⊳ No abstractions ⊳ No use of library functions Brain-dump Style @cristalopes #style1 name
  17. 17. STYLE #2 @cristalopes #style2 name
  18. 18. import re, string, sys stops = set(open("../stop_words.txt").read().split(",") + list(string.ascii_lowercase)) words = [x.lower() for x in re.split("[^a-zA-Z]+", open(sys.argv[1]).read()) if len(x) > 0 and x.lower() not in stops] unique_words = list(set(words)) unique_words.sort(lambda x, y: cmp(words.count(y), words.count(x))) print "n".join(["%s - %s" % (x, words.count(x)) for x in unique_words[:25]]) Credit: Laurie Tratt, Kings College London
  19. 19. import re, string, sys stops = set(open("../stop_words.txt").read().split(",") + list(string.ascii_lowercase)) words = [x.lower() for x in re.split("[^a-zA-Z]+", open(sys.argv[1]).read()) if len(x) > 0 and x.lower() not in stops] unique_words = list(set(words)) unique_words.sort(lambda x, y: cmp(words.count(y), words.count(x))) print "n".join(["%s - %s" % (x, words.count(x)) for x in unique_words[:25]])
  20. 20. import re, string, sys stops = set(open("../stop_words.txt").read().split(",") + list(string.ascii_lowercase)) words = [x.lower() for x in re.split("[^a-zA-Z]+", open(sys.argv[1]).read()) if len(x) > 0 and x.lower() not in stops] unique_words = list(set(words)) unique_words.sort(lambda x,y:cmp(words.count(y), words.count(x))) print "n".join(["%s - %s" % (x, words.count(x)) for x in unique_words[:25]])
  21. 21. Style #2 Main Characteristics ⊳ As few lines of code as possible @cristalopes #style2 name
  22. 22. Style #2 Main Characteristics ⊳ As few lines of code as possible Code Golf Style @cristalopes #style2 name
  23. 23. Style #2 Main Characteristics ⊳ As few lines of code as possible Try Hard Style @cristalopes #style2 name
  24. 24. STYLE #3 @cristalopes #style3 name
  25. 25. # # Main # read_file(sys.argv[1]) filter_normalize() scan() rem_stop_words() frequencies() sort() for tf in word_freqs[0:25]: print tf[0], ' - ', tf[1] def read_file(path): def filter_normalize(): def scan(): def rem_stop_words(): def frequencies(): def sort(): data=[] words=[] freqs=[]
  26. 26. Style #3 Main Characteristics ⊳ Procedural abstractions • maybe input, no output ⊳ Shared state ⊳ Larger problem solved by applying procedures, one after the other, changing the shared state @cristalopes #style3 name
  27. 27. Style #3 Main Characteristics ⊳ Procedural abstractions • maybe input, no output ⊳ Shared state ⊳ Commands Cook Book Style @cristalopes #style3 name
  28. 28. STYLE #4 @cristalopes #style4 name
  29. 29. # # Main # wfreqs=st(fq(r(sc(n(fc(rf(sys.argv[1]))))))) for tf in wfreqs[0:25]: print tf[0], ' - ', tf[1] def read_file(path): def filter(str_data): def scan(str_data): def rem_stop_words(wordl): def frequencies(wordl): def sort(word_freqs): def normalize(str_data): return ... return ... return ... return ... return ... return ... return ...
  30. 30. Style #4 Main Characteristics ⊳ Function abstractions • f: Input  Output ⊳ No shared state ⊳ Function composition f º g @cristalopes #style4 name
  31. 31. Style #4 Main Characteristics ⊳ Function abstractions • f: Input  Output ⊳ No shared state ⊳ Function composition f º g Chocolate Factory Style Image credit: Nykamp DQ, From Math Insight. http://mathinsight.org/image/function machines composed g f @cristalopes #style4 name
  32. 32. STYLE #5 @cristalopes #style5 name
  33. 33. def read_file(path, func): ... return func(…, normalize) def filter_chars(data, func): ... return func(…, scan) def normalize(data, func): ... return func(…,remove_stops) # Main w_freqs=read_file(sys.argv[1], filter_chars) for tf in w_freqs[0:25]: print tf[0], ' - ', tf[1] def scan(data, func): ... return func(…, frequencies) def remove_stops(data, func): ... return func(…, sort) Etc.
  34. 34. Style #5 Main Characteristics ⊳ Functions take one additional parameter, f • called at the end • given what would normally be the return value plus the next function @cristalopes #style5 name
  35. 35. Style #5 Main Characteristics ⊳ Functions take one additional parameter, f • called at the end • given what would normally be the return value plus the next function Crochet Style @cristalopes #style5 name
  36. 36. STYLE #6 @cristalopes #style6 name
  37. 37. class DataStorageManager(TFExercise): class TFExercise(): class StopWordManager(TFExercise): class WordFreqManager(TFExercise): class WordFreqController(TFExercise): # Main WordFreqController(sys.argv[1]).run() def words(self): def info(self): def info(self): def info(self): def info(self): def is_stop_word(self, word): def inc_count(self, word): def sorted(self): def run(self):
  38. 38. Style #6 Main Characteristics ⊳ Things, things and more things! • Capsules of data and procedures ⊳ Data is never accessed directly ⊳ Capsules can reappropriate procedures from other capsules @cristalopes #style6 name
  39. 39. Style #6 Main Characteristics ⊳ Things, things and more things! • Capsules of data and procedures ⊳ Data is never accessed directly ⊳ Capsules can reappropriate procedures from other capsules @cristalopes #style6 name Kingdom of Nouns Style
  40. 40. STYLE #7 @cristalopes #style7 name
  41. 41. class DataStorageManager(): class StopWordManager(): class WordFrequencyManager(): class WordFrequencyController(): def dispatch(self, message): def dispatch(self, message): def dispatch(self, message): def dispatch(self, message): # Main wfcntrl = WordFrequencyController() wfcntrl.dispatch([‘init’,sys.argv[1]]) wfcntrl.dispatch([‘run’])
  42. 42. Style #7 Main Characteristics ⊳ (Similar to #6) ⊳ Capsules receive messages via single receiving procedure @cristalopes #style7 name
  43. 43. Style #7 Main Characteristics ⊳ (Similar to #6) ⊳ Capsules receive messages via single receiving procedure @cristalopes #style7 name Letterbox Style
  44. 44. STYLE #8 @cristalopes #style8 name
  45. 45. # Main splits = map(split_words, partition(read_file(sys.argv[1]), 200)) splits.insert(0, []) word_freqs = sort(reduce(count_words, splits)) for tf in word_freqs[0:25]: print tf[0], ' - ', tf[1]
  46. 46. def split_words(data_str) """ Takes a string (many lines), filters, normalizes to lower case, scans for words, and filters the stop words. Returns a list of pairs (word, 1), so [(w1, 1), (w2, 1), ..., (wn, 1)] """ ... result = [] words = _rem_stop_words(_scan(_normalize(_filter(data_str)))) for w in words: result.append((w, 1)) return result
  47. 47. def count_words(pairs_list_1, pairs_list_2) """ Takes two lists of pairs of the form [(w1, 1), ...] and returns a list of pairs [(w1, frequency), ...], where frequency is the sum of all occurrences """ mapping = dict((k, v) for k, v in pairs_list_1) for p in pairs_list_2: if p[0] in mapping: mapping[p[0]] += p[1] else: mapping[p[0]] = 1 return mapping.items()
  48. 48. Style #8 Main Characteristics ⊳ Two key abstractions: map(f, chunks) and reduce(g, results) @cristalopes #style8 name
  49. 49. Style #8 Main Characteristics ⊳ Two key abstractions: map(f, chunks) and reduce(g, results) @cristalopes #style8 name Map-Reduce Style
  50. 50. STYLE #9 @cristalopes #style9 name
  51. 51. # Main connection = sqlite3.connect(':memory:') create_db_schema(connection) load_file_into_database(sys.argv[1], connection) # Now, let's query c = connection.cursor() c.execute("SELECT value, COUNT(*) as C FROM words GROUP BY value ORDER BY C DESC") for i in range(25): row = c.fetchone() if row != None: print row[0] + ' - ' + str(row[1]) connection.close()
  52. 52. def create_db_schema(connection): c = connection.cursor() c.execute('''CREATE TABLE documents(id PRIMARY KEY AUTOINCREMENT, name)''' c.execute('''CREATE TABLE words(id, doc_id, value)''') c.execute('''CREATE TABLE characters(id, word_id, value)''') connection.commit() c.close()
  53. 53. # Now let's add data to the database # Add the document itself to the database c = connection.cursor() c.execute("INSERT INTO documents (name) VALUES (?)", (path_to_f c.execute("SELECT id from documents WHERE name=?", (path_to_fil doc_id = c.fetchone()[0] # Add the words to the database c.execute("SELECT MAX(id) FROM words") row = c.fetchone() word_id = row[0] if word_id == None: word_id = 0 for w in words: c.execute("INSERT INTO words VALUES (?, ?, ?)", (word_id, d # Add the characters to the database char_id = 0 for char in w: c.execute("INSERT INTO characters VALUES (?, ?, ?)", (c char_id += 1 word_id += 1 connection.commit() c.close()
  54. 54. Style #9 Main Characteristics ⊳ Entities and relations between them ⊳ Query engine • Declarative queries @cristalopes #style9 name
  55. 55. Style #9 Main Characteristics ⊳ Entities and relations between them ⊳ Query engine • Declarative queries @cristalopes #style9 name Tabular Style
  56. 56. Take Home ⊳ Many ways of solving problems • Know them, assess them ⊳ Constraints are important for communication • Make them explicit ⊳ Don’t be hostage of one way of doing things
  57. 57. Available on Amazon
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×