x871kx6167ss7 Skrevet 27. september 2011 Rapporter Del Skrevet 27. september 2011 torbøjrn: Skal innrømme at koden skrev ikke var god (kan unskylde meg litt med halveis-krav om en-bokstav-variabler i oppgaven). Koden jeg hadde så slik ut: def foobar(): t = ... def foo(): ... t ... for t in ...: foo() Har aldri programmert seriøst i python, men de gangene jeg har programmert i python, så har jeg alltid hatt en uggen følelse av å ikke forstå helt hvordan skopet fungerer. kgun: Jeg er sånn sett enig. Dersom man sier man kan python, så følger det at man skal kunne hvordan skop fungerer i python. Jeg påstår ikke å kunne python. men jeg synes det ble gjort et dårlig valg i "designet" når for-løkker ikke innfører ferske bindinger. Samtidig så har python en særegen måte å håndtere variabler på, så det er sikkert mye å ta hensyn til. Angående argumentet som kort oppsummert er "det er praktisk i noen tilfeller", så synes jeg det blir i baner med "det er praktisk med goto i noen tilfeller"; jeg er forsåvidt enig i begge påstanene, men det er sånn sett ikke det jeg kritiserer. For meg så brøyter for-løkken med "principle of least suprise". Lenke til kommentar
torbjørn marø Skrevet 27. september 2011 Rapporter Del Skrevet 27. september 2011 "principle of least suprise". Dette prinsippet er avhengig av hva man er vandt til, og således forskjellig for alle. Matz designet f.eks. Ruby etter dette prinsippet, men påpeket at han mente "least surpise for me!". Utviklere som begynte med Python/Ruby/javaScript, for så å gå videre til Java/C# ville kanskje bli svært overrasket når de oppdaget at de ikke kan benytte iterasjonsvariabelen etter at løkken var avsluttet. Lenke til kommentar
epsil Skrevet 27. september 2011 Rapporter Del Skrevet 27. september 2011 (endret) Hva ville du tro at denne Python snutten skriver ut? l = [] for i in range(5): l.append(lambda: i) for f in l: sys.stdout.write("f returnerer " + str(f()) + "\n") Hm … Uavhengig av hva slags skop for har, så er det bare én binding her. Selv om funksjonene i l lukker om i (fordi Python har closures), så vil de alle ende opp med å returnere den samme verdien. I dette tilfellet 4, ettersom range(5) returnerer [0, 1, 2, 3, 4]. For å få forskjellige verdier, måtte for-løkken ha laget en ny binding for hver iterasjon. I Lisp ville dette bety å omslutte løkkekroppen med (let ...). Dette ville også gjøre det umulig å tukle med tellervariabelen, dvs. løkkekroppen ville kunne inkrementere eller dekrementere i uten konsekvenser for påfølgende iterasjoner. Endret 4. april 2012 av epsil Lenke til kommentar
x871kx6167ss7 Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 Dette prinsippet er avhengig av hva man er vandt til, og således forskjellig for alle. Matz designet f.eks. Ruby etter dette prinsippet, men påpeket at han mente "least surpise for me!". Selvfølgelig. Utviklere som begynte med Python/Ruby/javaScript, for så å gå videre til Java/C# ville kanskje bli svært overrasket når de oppdaget at de ikke kan benytte iterasjonsvariabelen etter at løkken var avsluttet. Samtidig så vil jeg si at syntaksen i java er gangske konsistent med å vise om man gjenbruker eller introduserer en ny binding: for (int i = 0; i < 10; i++) { } System.out.println(i); /* compile-time error: i ikke i skopet */ i forhold til int i; for (i = 0; i < 10; i++) { } System.out.println(i); /* skriver ut 10 */ Hva ville du tro at denne Python snutten skriver ut? l = [] for i in range(5): l.append(lambda: i) for f in l: sys.stdout.write("f returnerer " + str(f()) + "\n") Hm … Uavhengig av hva slags skop for har, så er det bare én binding her. Selv om funksjonene i l lukker om i (fordi Python har closures), så vil de alle ende opp med å returnere den samme verdien. I dette tilfellet 4, ettersom range(5) returnerer [0, 1, 2, 3, 4]. For å få forskjellige verdier, måtte for-løkken ha laget en ny binding for hver iterasjon. I Lisp ville dette bety å omslutte løkkekroppen med (let ...). Dette ville også gjøre det umulig å «tukle» med tellervariabelen, dvs. løkkekroppen kunne inkrementere eller dekrementere i uten at det fikk konsekvenser for påfølgende iterasjoner. Her er jeg enig med deg epsi; det var ikke slik at jeg forventet at for-løkken skulle introdusere en ny binding for hver gjennomgang. 1 Lenke til kommentar
snippsat Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 (endret) Hva ville du tro at denne Python snutten skriver ut? l = [] for i in range(5): l.append(lambda: i) for f in l: sys.stdout.write("f returnerer " + str(f()) + "\n") Komprimere den litt for gøy. >>> [f() for f in ([lambda : i for i in range(5)])] [4, 4, 4, 4, 4] Vet ikke om dette blåses litt opp,hører sjeldent om det vi diskuterer her med scope er noe problem i det hele tatt. Endret 28. september 2011 av SNIPPSAT Lenke til kommentar
asicman Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 Uavhengig av hva slags skop for har, så er det bare én binding her. Det er korrekt. Det er ikke alltid like enkelt å skille de to, spesielt hvis man ikke har vært eksponert for språk som gjør det klart. Jeg husker ikke helt detaljene, men jeg så tilsvarende «feil» i noe GUI kode som skulle returnere callback funksjoner som laget forskjellige GUI objekter. Så ble det bare det siste objektet som ble returnert av alle funksjonene. Som du sier så kan man introdusere en ny binding i Lisp med «let». I Python er det ikke like enkelt å lage en ny binding. Jeg kan tenke på en måte i koden ovenfor som ikke er spesielt elegant. 1 Lenke til kommentar
asicman Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 Komprimere den litt for gøy. >>> [f() for f in ([lambda : i for i in range(5)])] [4, 4, 4, 4, 4] Kanskje du kan skrive den om slik at den lager funksjoner som returnerer [0, 1, 2, 3, 4]? Gjerne med list comprehension. I Common Lisp kan man skrive: (loop for f in (loop for i from 0 below 5 collect (let ((i i)) (lambda () i))) collect (funcall f)) Ville sannsynligvis ikke ha brukt samme navn i let, men bare for å vise at den vil gjemme den som er i scopet utenfor. I Python blir det å gjøre et hack med å lage en ny funksjon som oppretter en ny binding. Hvis ingen har en mer elegant løsning? Lenke til kommentar
GeirGrusom Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 Hva ville du tro at denne Python snutten skriver ut? l = [] for i in range(5): l.append(lambda: i) for f in l: sys.stdout.write("f returnerer " + str(f()) + "\n") f returnerer 4 f returnerer 4 f returnerer 4 f returnerer 4 f returnerer 4 Ville jeg tro, ettersom det er en closure av i, ikke verdien til i. Selv om den faller ut av scope, så skal den ikke forsvinne fra closuren (det er jo derfor det heter closure). Lenke til kommentar
asicman Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 f returnerer 4 f returnerer 4 f returnerer 4 f returnerer 4 f returnerer 4 Det er korrekt. Se også mitt svar til epsi 07:55. Så er det å lage en ny binding i Python. En måte å gjøre det på er å gjøre et hack ved å lage en ekstra funksjon i mangel av noe som «let» for å lage en ny binding: def hack (i): return (lambda: i) l = [] for i in range(5): l.append(hack(i)) for f in l: sys.stdout.write("f returnerer " + str(f()) + "\n") Jeg vet ikke om noen andre har noen bedre forslag? Nå er jeg ingen Haskell ekspert, men jeg har forstått det slik at list comprehension binder iteratoren slik at i Haskell så virker det samme i motsetning til Python: map ($ ()) [\y -> x | x <- [0 .. 4]] -> [0,1,2,3,4] Men det er mulig jeg blir lurt av lazy eval her? Noen Haskell eksperter her som kan svare? Lenke til kommentar
Gjest Slettet+9871234 Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 (endret) Der finnes ihvertfall noen her: http://fp.cs.nott.ac.uk/ Rart med engelskmennene. Man hører ikke så mye om dem, men de har noen gode programmerings miljøre som for eksempel rundt Professor Gordon Blair http://www.comp.lancs.ac.uk/department/staff.php?name=gordon ved Lancaster universitetet. De er relativt sterke på "delegation" så vidt jeg har forstått. Delegation er relativt grundig behandlet i den "eviggrønne klassikeren": Gordon Blair, John Gallagher, David Hutchison and Doug Shephard (1991): "Object Oriented Languages, Systems and Applications." Pitman Publishing ISBN 0-273-03132-5 Opp med hånden de som misliker følgende kode: def fibonacci(max): a, b = 0, 1 while a < max: yield a a, b = b, a+b for n in fibonacci(1000000000000000000000000000000000000000000000000000000): print (n), Endret 28. september 2011 av Slettet+9871234 Lenke til kommentar
snippsat Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 (endret) Kanskje du kan skrive den om slik at den lager funksjoner som returnerer [0, 1, 2, 3, 4]? Gjerne med list comprehension. Tjaa man kan forandre parenthese da returneres et generator object. I forhold til list comprehension vil den da ikke uføres [0, 1, 2, 3, 4] ved hver loop. >>> [f() for f in ((lambda : i for i in range(5)))] [0, 1, 2, 3, 4] >>> g = (lambda : i for i in range(5)) >>> g <generator object <genexpr> at 0x00EFA300> >>> l = [lambda : i for i in range(5)] >>> l [<function <lambda> at 0x00EF4BB0>, <function <lambda> at 0x00E884B0>, <function <lambda> at 0x00E88E30>, <function <lambda> at 0x00E88F30>, <function <lambda> at 0x00E88370>] Endret 28. september 2011 av SNIPPSAT Lenke til kommentar
x871kx6167ss7 Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 map ($ ()) [\y -> x | x <- [0 .. 4]] -> [0,1,2,3,4] Men det er mulig jeg blir lurt av lazy eval her? Noen Haskell eksperter her som kan svare? Jeg er ikke noen haskell-ekspert. Haskell er fullstending funksjonellt, følgelig innføres det en ny binding for hver verdi av x. Lenke til kommentar
torbjørn marø Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 Opp med hånden de som misliker følgende kode: def fibonacci(max): a, b = 0, 1 while a < max: yield a a, b = b, a+b for n in fibonacci(1000000000000000000000000000000000000000000000000000000): print (n), Jeg synes den var litt søt Lenke til kommentar
Gjest Slettet+9871234 Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 Jeg synes den var litt søt Jeg er jo som kjent noen ganger en tut og kjør pragmatisk programmerer: http://pragprog.com/book/tpp/the-pragmatic-programmer Du har vel allerede et eksemplar av denne http://pragprog.com/book/shcloj2/programming-clojure antar jeg. Lenke til kommentar
torbjørn marø Skrevet 28. september 2011 Rapporter Del Skrevet 28. september 2011 Jeg er jo som kjent noen ganger en tut og kjør pragmatisk programmerer: http://pragprog.com/book/tpp/the-pragmatic-programmer Du har vel allerede et eksemplar av denne http://pragprog.com/book/shcloj2/programming-clojure antar jeg. Jeg elsker PragProg-bøkene - akkurat nå leser jeg http://pragprog.com/book/tbcoffee/coffeescript Anbefaler også alle å ta en titt på Pragmatic Thinking and Learning: Refactor Your Wetware. Og selvfølgelig Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages! Lenke til kommentar
Gjest Slettet+9871234 Skrevet 29. september 2011 Rapporter Del Skrevet 29. september 2011 (endret) Jeg elsker PragProg-bøkene - ... Mange setter the pragmatic programmer som en av sine favorittbøker. Andre foretrekker kanskje O'Reilly's "Beautiful Code" http://shop.oreilly.com/product/9780596510046.do som dog bare er ratet med 4 stjerner hos O'Reilly. Manning har også noen svært pedagogiske bøker, blant annet denne http://www.manning.com/sande/ hvor en far lærer sin sønn programmering (i Python). De lanserer i oktober 2011 blant annet boken: "Clojure in Action" http://www.manning.com/rathore/ som du sikkert kjenner. Her http://stuartsierra.com/ er en Clojure fyr du muligens må titte litt på. Se også Clojure: Lisp for the Real World Professionalism in programming antar jeg også at du kjenner. Der finner man under "Book Reviews" en omtale av en av mine favorittbøker http://www.acceleratedcpp.com/ Endret 29. september 2011 av Slettet+9871234 Lenke til kommentar
GeirGrusom Skrevet 3. oktober 2011 Rapporter Del Skrevet 3. oktober 2011 Sitter og skrive en ekstra compiler (gjør om Expression til C) for BASIC varianten, men klør meg litt i hodet over dokumentasjonen til Microsoft på noen uttrykk. Føgende funksjon: public static UnaryExpression Quote(Expression expression) A UnaryExpression that has the NodeType property equal to Quote and the Operand property set to the specified value. Duh! Men hva ER Quote til? :S De som skrev dette burde fått fik for å kaste bort tid ved å skrive en fullstendig verdiløs forklaring på hva funksjonen gjør. Faktisk er hele dokumentasjonen på System.Linq.Expressions ganske mangelfull. Lenke til kommentar
haarod Skrevet 3. oktober 2011 Rapporter Del Skrevet 3. oktober 2011 (endret) Jeg får ikke til å bruke math-funksjoner i Python. Jeg prøver bare å skrive print(math.floor(1.5)) for eksempel, men da får jeg bare en standard feilmelding om at det ligger en feil i første linje. Må jeg importere et bibliotek eller noe tilsvarende? Jeg bruker python 3.2. Jeg har funnet denne dokumentasjonen som sier at denne modulen alltid er tilgjengelig: http://docs.python.org/py3k/library/math.html#module-math EDIT: Jeg har også prøvd i python 2.7, og selv om det står eksplisitt i dokumentasjonen til begge at modulen skal være bygget inn så fungerer ingen matte-funksjoner. Hva er det jeg mangler? Det står bare at floor/ceil/exp ikke er "defined".. Endret 3. oktober 2011 av haarod Lenke til kommentar
haarod Skrevet 3. oktober 2011 Rapporter Del Skrevet 3. oktober 2011 (endret) Det var ikke verre enn det altså.. Takk skal du ha! Endret 3. oktober 2011 av haarod Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå