@ Programmatori esterofag.
#61 Guest_LoneWolf_*
Inviato 24 marzo 2011 - 22:56
Tutti su java?
#62
Inviato 24 marzo 2011 - 23:02
trallallero ha postato codice c++.Ma il vecchio C++ non lo utilizza più nessuno?
Tutti su java?
Io sono tornato da poco a java dopo qualche anno di C#.
E ovviamente python e ruby per scriptini.
#63 Guest_LoneWolf_*
Inviato 24 marzo 2011 - 23:04
trallallero ha postato codice c++.?[/url]":1pwo7t3e] Ma il vecchio C++ non lo utilizza più nessuno?
Tutti su java?
Io sono tornato da poco a java dopo qualche anno di C#.
E ovviamente python e ruby per scriptini.
Ah, ok, altrimenti avrei buttato il mio tempo.
#64
Inviato 25 marzo 2011 - 08:28
I commenti nel codice, a meno di casi particolari, sono un indice che il codice e' scritto male.
<...cut bullshit... >
sfornando di nuovo queste massime filosofiche assurde che nel mondo dell'informatica non devono esistere.
Ma adesso capisco, visto che usi
Io sono tornato da poco a java dopo qualche anno di C#.
E ovviamente python e ruby per scriptini.
Vuoi vedere com'è fatto il Python che usi ? hai mai aperto un file sorgente ?
ne prendo uno a caso (codecs.c):
/* ------------------------------------------------------------------------ Python Codec Registry and support functions Written by Marc-Andre Lemburg (mal@lemburg.com). Copyright (c) Corporation for National Research Initiatives. ------------------------------------------------------------------------ */ #include "Python.h" #include /* --- Codec Registry ----------------------------------------------------- */ /* Import the standard encodings package which will register the first codec search function. This is done in a lazy way so that the Unicode implementation does not downgrade startup time of scripts not needing it. ImportErrors are silently ignored by this function. Only one try is made. */ static int _PyCodecRegistry_Init(void); /* Forward */ int PyCodec_Register(PyObject *search_function) { PyInterpreterState *interp = PyThreadState_GET()->interp; if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) goto onError; if (search_function == NULL) { PyErr_BadArgument(); goto onError; } if (!PyCallable_Check(search_function)) { PyErr_SetString(PyExc_TypeError, "argument must be callable"); goto onError; } return PyList_Append(interp->codec_search_path, search_function); onError: return -1; } /* Convert a string to a normalized Python string: all characters are converted to lower case, spaces are replaced with underscores. */ static PyObject *normalizestring(const char *string) { register size_t i; size_t len = strlen(string); char *p; PyObject *v; if (len > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "string is too large"); return NULL; } p = PyMem_Malloc(len + 1); if (p == NULL) return NULL; for (i = 0; i < len; i++) { register char ch = string[i]; if (ch == ' ') ch = '-'; else ch = tolower(Py_CHARMASK(ch)); p[i] = ch; } p[i] = '\0'; v = PyUnicode_FromString(p); if (v == NULL) return NULL; PyMem_Free(p); return v; } /* Lookup the given encoding and return a tuple providing the codec facilities. The encoding string is looked up converted to all lower-case characters. This makes encodings looked up through this mechanism effectively case-insensitive. If no codec is found, a LookupError is set and NULL returned. As side effect, this tries to load the encodings package, if not yet done. This is part of the lazy load strategy for the encodings package. */ PyObject *_PyCodec_Lookup(const char *encoding) { PyInterpreterState *interp; PyObject *result, *args = NULL, *v; Py_ssize_t i, len; if (encoding == NULL) { PyErr_BadArgument(); goto onError; } interp = PyThreadState_GET()->interp; if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) goto onError; /* Convert the encoding to a normalized Python string: all characters are converted to lower case, spaces and hyphens are replaced with underscores. */ v = normalizestring(encoding); if (v == NULL) goto onError; PyUnicode_InternInPlace(&v); /* First, try to lookup the name in the registry dictionary */ result = PyDict_GetItem(interp->codec_search_cache, v); if (result != NULL) { Py_INCREF(result); Py_DECREF(v); return result; } /* Next, scan the search functions in order of registration */ args = PyTuple_New(1); if (args == NULL) goto onError; PyTuple_SET_ITEM(args,0,v); len = PyList_Size(interp->codec_search_path); if (len < 0) goto onError; if (len == 0) { PyErr_SetString(PyExc_LookupError, "no codec search functions registered: " "can't find encoding"); goto onError; } for (i = 0; i < len; i++) { PyObject *func; func = PyList_GetItem(interp->codec_search_path, i); if (func == NULL) goto onError; result = PyEval_CallObject(func, args); if (result == NULL) goto onError; if (result == Py_None) { Py_DECREF(result); continue; } if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) { PyErr_SetString(PyExc_TypeError, "codec search functions must return 4-tuples"); Py_DECREF(result); goto onError; } break; } if (i == len) { /* XXX Perhaps we should cache misses too ? */ PyErr_Format(PyExc_LookupError, "unknown encoding: %s", encoding); goto onError; } /* Cache and return the result */ if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) { Py_DECREF(result); goto onError; } Py_DECREF(args); return result; onError: Py_XDECREF(args); return NULL; } /* Codec registry encoding check API. */ int PyCodec_KnownEncoding(const char *encoding) { PyObject *codecs; codecs = _PyCodec_Lookup(encoding); if (!codecs) { PyErr_Clear(); return 0; } else { Py_DECREF(codecs); return 1; } } static PyObject *args_tuple(PyObject *object, const char *errors) { PyObject *args; args = PyTuple_New(1 + (errors != NULL)); if (args == NULL) return NULL; Py_INCREF(object); PyTuple_SET_ITEM(args,0,object); if (errors) { PyObject *v; v = PyUnicode_FromString(errors); if (v == NULL) { Py_DECREF(args); return NULL; } PyTuple_SET_ITEM(args, 1, v); } return args; } /* Helper function to get a codec item */ static PyObject *codec_getitem(const char *encoding, int index) { PyObject *codecs; PyObject *v; codecs = _PyCodec_Lookup(encoding); if (codecs == NULL) return NULL; v = PyTuple_GET_ITEM(codecs, index); Py_DECREF(codecs); Py_INCREF(v); return v; } /* Helper function to create an incremental codec. */ static PyObject *codec_getincrementalcodec(const char *encoding, const char *errors, const char *attrname) { PyObject *codecs, *ret, *inccodec; codecs = _PyCodec_Lookup(encoding); if (codecs == NULL) return NULL; inccodec = PyObject_GetAttrString(codecs, attrname); Py_DECREF(codecs); if (inccodec == NULL) return NULL; if (errors) ret = PyObject_CallFunction(inccodec, "s", errors); else ret = PyObject_CallFunction(inccodec, NULL); Py_DECREF(inccodec); return ret; } /* Helper function to create a stream codec. */ static PyObject *codec_getstreamcodec(const char *encoding, PyObject *stream, const char *errors, const int index) { PyObject *codecs, *streamcodec, *codeccls; codecs = _PyCodec_Lookup(encoding); if (codecs == NULL) return NULL; codeccls = PyTuple_GET_ITEM(codecs, index); if (errors != NULL) streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors); else streamcodec = PyObject_CallFunction(codeccls, "O", stream); Py_DECREF(codecs); return streamcodec; } /* Convenience APIs to query the Codec registry. All APIs return a codec object with incremented refcount. */ PyObject *PyCodec_Encoder(const char *encoding) { return codec_getitem(encoding, 0); } PyObject *PyCodec_Decoder(const char *encoding) { return codec_getitem(encoding, 1); } PyObject *PyCodec_IncrementalEncoder(const char *encoding, const char *errors) { return codec_getincrementalcodec(encoding, errors, "incrementalencoder"); } PyObject *PyCodec_IncrementalDecoder(const char *encoding, const char *errors) { return codec_getincrementalcodec(encoding, errors, "incrementaldecoder"); } PyObject *PyCodec_StreamReader(const char *encoding, PyObject *stream, const char *errors) { return codec_getstreamcodec(encoding, stream, errors, 2); } PyObject *PyCodec_StreamWriter(const char *encoding, PyObject *stream, const char *errors) { return codec_getstreamcodec(encoding, stream, errors, 3); } /* Encode an object (e.g. an Unicode object) using the given encoding and return the resulting encoded object (usually a Python string). errors is passed to the encoder factory as argument if non-NULL. */ PyObject *PyCodec_Encode(PyObject *object, const char *encoding, const char *errors) { PyObject *encoder = NULL; PyObject *args = NULL, *result = NULL; PyObject *v = NULL; encoder = PyCodec_Encoder(encoding); if (encoder == NULL) goto onError; args = args_tuple(object, errors); if (args == NULL) goto onError; result = PyEval_CallObject(encoder, args); if (result == NULL) goto onError; if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 2) { PyErr_SetString(PyExc_TypeError, "encoder must return a tuple (object, integer)"); goto onError; } v = PyTuple_GET_ITEM(result,0); Py_INCREF(v); /* We don't check or use the second (integer) entry. */ Py_DECREF(args); Py_DECREF(encoder); Py_DECREF(result); return v; onError: Py_XDECREF(result); Py_XDECREF(args); Py_XDECREF(encoder); return NULL; } /* Decode an object (usually a Python string) using the given encoding and return an equivalent object (e.g. an Unicode object). errors is passed to the decoder factory as argument if non-NULL. */ PyObject *PyCodec_Decode(PyObject *object, const char *encoding, const char *errors) { PyObject *decoder = NULL; PyObject *args = NULL, *result = NULL; PyObject *v; decoder = PyCodec_Decoder(encoding); if (decoder == NULL) goto onError; args = args_tuple(object, errors); if (args == NULL) goto onError; result = PyEval_CallObject(decoder,args); if (result == NULL) goto onError; if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 2) { PyErr_SetString(PyExc_TypeError, "decoder must return a tuple (object,integer)"); goto onError; } v = PyTuple_GET_ITEM(result,0); Py_INCREF(v); /* We don't check or use the second (integer) entry. */ Py_DECREF(args); Py_DECREF(decoder); Py_DECREF(result); return v; onError: Py_XDECREF(args); Py_XDECREF(decoder); Py_XDECREF(result); return NULL; } /* Register the error handling callback function error under the name name. This function will be called by the codec when it encounters an unencodable characters/undecodable bytes and doesn't know the callback name, when name is specified as the error parameter in the call to the encode/decode function. Return 0 on success, -1 on error */ int PyCodec_RegisterError(const char *name, PyObject *error) { PyInterpreterState *interp = PyThreadState_GET()->interp; if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) return -1; if (!PyCallable_Check(error)) { PyErr_SetString(PyExc_TypeError, "handler must be callable"); return -1; } return PyDict_SetItemString(interp->codec_error_registry, (char *)name, error); } /* Lookup the error handling callback function registered under the name error. As a special case NULL can be passed, in which case the error handling callback for strict encoding will be returned. */ PyObject *PyCodec_LookupError(const char *name) { PyObject *handler = NULL; PyInterpreterState *interp = PyThreadState_GET()->interp; if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) return NULL; if (name==NULL) name = "strict"; handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name); if (!handler) PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); else Py_INCREF(handler); return handler; } static void wrong_exception_type(PyObject *exc) { PyObject *type = PyObject_GetAttrString(exc, "__class__"); if (type != NULL) { PyObject *name = PyObject_GetAttrString(type, "__name__"); Py_DECREF(type); if (name != NULL) { PyErr_Format(PyExc_TypeError, "don't know how to handle %S in error callback", name); Py_DECREF(name); } } } PyObject *PyCodec_StrictErrors(PyObject *exc) { if (PyExceptionInstance_Check(exc)) PyErr_SetObject(PyExceptionInstance_Class(exc), exc); else PyErr_SetString(PyExc_TypeError, "codec must pass exception instance"); return NULL; } PyObject *PyCodec_IgnoreErrors(PyObject *exc) { Py_ssize_t end; if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; } else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { if (PyUnicodeDecodeError_GetEnd(exc, &end)) return NULL; } else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { if (PyUnicodeTranslateError_GetEnd(exc, &end)) return NULL; } else { wrong_exception_type(exc); return NULL; } /* ouch: passing NULL, 0, pos gives None instead of u'' */ return Py_BuildValue("(u#n)", &end, 0, end); } PyObject *PyCodec_ReplaceErrors(PyObject *exc) { PyObject *restuple; Py_ssize_t start; Py_ssize_t end; Py_ssize_t i; if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { PyObject *res; Py_UNICODE *p; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; res = PyUnicode_FromUnicode(NULL, end-start); if (res == NULL) return NULL; for (p = PyUnicode_AS_UNICODE(res), i = start; i<end; ++p, ++i) *p = '?'; restuple = Py_BuildValue("(On)", res, end); Py_DECREF(res); return restuple; } else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER; if (PyUnicodeDecodeError_GetEnd(exc, &end)) return NULL; return Py_BuildValue("(u#n)", &res, 1, end); } else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { PyObject *res; Py_UNICODE *p; if (PyUnicodeTranslateError_GetStart(exc, &start)) return NULL; if (PyUnicodeTranslateError_GetEnd(exc, &end)) return NULL; res = PyUnicode_FromUnicode(NULL, end-start); if (res == NULL) return NULL; for (p = PyUnicode_AS_UNICODE(res), i = start; i<end; ++p, ++i) *p = Py_UNICODE_REPLACEMENT_CHARACTER; restuple = Py_BuildValue("(On)", res, end); Py_DECREF(res); return restuple; } else { wrong_exception_type(exc); return NULL; } } PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) { if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { PyObject *restuple; PyObject *object; Py_ssize_t start; Py_ssize_t end; PyObject *res; Py_UNICODE *p; Py_UNICODE *startp; Py_UNICODE *outp; int ressize; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; startp = PyUnicode_AS_UNICODE(object); for (p = startp+start, ressize = 0; p < startp+end; ++p) { if (*p<10) ressize += 2+1+1; else if (*p<100) ressize += 2+2+1; else if (*p<1000) ressize += 2+3+1; else if (*p<10000) ressize += 2+4+1; #ifndef Py_UNICODE_WIDE else ressize += 2+5+1; #else else if (*p<100000) ressize += 2+5+1; else if (*p<1000000) ressize += 2+6+1; else ressize += 2+7+1; #endif } /* allocate replacement */ res = PyUnicode_FromUnicode(NULL, ressize); if (res == NULL) { Py_DECREF(object); return NULL; } /* generate replacement */ for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); p < startp+end; ++p) { Py_UNICODE c = *p; int digits; int base; *outp++ = '&'; *outp++ = '#'; if (*p<10) { digits = 1; base = 1; } else if (*p<100) { digits = 2; base = 10; } else if (*p<1000) { digits = 3; base = 100; } else if (*p<10000) { digits = 4; base = 1000; } #ifndef Py_UNICODE_WIDE else { digits = 5; base = 10000; } #else else if (*p<100000) { digits = 5; base = 10000; } else if (*p<1000000) { digits = 6; base = 100000; } else { digits = 7; base = 1000000; } #endif while (digits-->0) { *outp++ = '0' + c/base; c %= base; base /= 10; } *outp++ = ';'; } restuple = Py_BuildValue("(On)", res, end); Py_DECREF(res); Py_DECREF(object); return restuple; } else { wrong_exception_type(exc); return NULL; } } static Py_UNICODE hexdigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) { #ifndef Py_UNICODE_WIDE #define IS_SURROGATE_PAIR(p, end) \ (*p >= 0xD800 && *p <= 0xDBFF && (p + 1) < end && \ *(p + 1) >= 0xDC00 && *(p + 1) <= 0xDFFF) #else #define IS_SURROGATE_PAIR(p, end) 0 #endif if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { PyObject *restuple; PyObject *object; Py_ssize_t start; Py_ssize_t end; PyObject *res; Py_UNICODE *p; Py_UNICODE *startp; Py_UNICODE *outp; int ressize; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; startp = PyUnicode_AS_UNICODE(object); for (p = startp+start, ressize = 0; p < startp+end; ++p) { #ifdef Py_UNICODE_WIDE if (*p >= 0x00010000) ressize += 1+1+8; else #endif if (*p >= 0x100) { if (IS_SURROGATE_PAIR(p, startp+end)) { ressize += 1+1+8; ++p; } else ressize += 1+1+4; } else ressize += 1+1+2; } res = PyUnicode_FromUnicode(NULL, ressize); if (res==NULL) return NULL; for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); p < startp+end; ++p) { Py_UCS4 c = (Py_UCS4) *p; *outp++ = '\\'; if (IS_SURROGATE_PAIR(p, startp+end)) { c = ((*p & 0x3FF) << 10) + (*(p + 1) & 0x3FF) + 0x10000; ++p; } if (c >= 0x00010000) { *outp++ = 'U'; *outp++ = hexdigits[(c>>28)&0xf]; *outp++ = hexdigits[(c>>24)&0xf]; *outp++ = hexdigits[(c>>20)&0xf]; *outp++ = hexdigits[(c>>16)&0xf]; *outp++ = hexdigits[(c>>12)&0xf]; *outp++ = hexdigits[(c>>:pua:&0xf]; } else if (c >= 0x100) { *outp++ = 'u'; *outp++ = hexdigits[(c>>12)&0xf]; *outp++ = hexdigits[(c>>:pua:&0xf]; } else *outp++ = 'x'; *outp++ = hexdigits[(c>>4)&0xf]; *outp++ = hexdigits[c&0xf]; } restuple = Py_BuildValue("(On)", res, end); Py_DECREF(res); Py_DECREF(object); return restuple; } else { wrong_exception_type(exc); return NULL; } #undef IS_SURROGATE_PAIR } /* This handler is declared static until someone demonstrates a need to call it directly. */ static PyObject * PyCodec_SurrogatePassErrors(PyObject *exc) { PyObject *restuple; PyObject *object; Py_ssize_t start; Py_ssize_t end; PyObject *res; if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { Py_UNICODE *p; Py_UNICODE *startp; char *outp; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; startp = PyUnicode_AS_UNICODE(object); res = PyBytes_FromStringAndSize(NULL, 3*(end-start)); if (!res) { Py_DECREF(object); return NULL; } outp = PyBytes_AsString(res); for (p = startp+start; p < startp+end; p++) { Py_UNICODE ch = *p; if (ch < 0xd800 || ch > 0xdfff) { /* Not a surrogate, fail with original exception */ PyErr_SetObject(PyExceptionInstance_Class(exc), exc); Py_DECREF(res); Py_DECREF(object); return NULL; } *outp++ = (char)(0xe0 | (ch >> 12)); *outp++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *outp++ = (char)(0x80 | (ch & 0x3f)); } restuple = Py_BuildValue("(On)", res, end); Py_DECREF(res); Py_DECREF(object); return restuple; } else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { unsigned char *p; Py_UNICODE ch = 0; if (PyUnicodeDecodeError_GetStart(exc, &start)) return NULL; if (!(object = PyUnicodeDecodeError_GetObject(exc))) return NULL; if (!(p = (unsigned char*)PyBytes_AsString(object))) { Py_DECREF(object); return NULL; } /* Try decoding a single surrogate character. If there are more, let the codec call us again. */ p += start; if ((p[0] & 0xf0) == 0xe0 || (p[1] & 0xc0) == 0x80 || (p[2] & 0xc0) == 0x80) { /* it's a three-byte code */ ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f); if (ch < 0xd800 || ch > 0xdfff) /* it's not a surrogate - fail */ ch = 0; } Py_DECREF(object); if (ch == 0) { PyErr_SetObject(PyExceptionInstance_Class(exc), exc); return NULL; } return Py_BuildValue("(u#n)", &ch, 1, start+3); } else { wrong_exception_type(exc); return NULL; } } static PyObject * PyCodec_SurrogateEscapeErrors(PyObject *exc) { PyObject *restuple; PyObject *object; Py_ssize_t start; Py_ssize_t end; PyObject *res; if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { Py_UNICODE *p; Py_UNICODE *startp; char *outp; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; startp = PyUnicode_AS_UNICODE(object); res = PyBytes_FromStringAndSize(NULL, end-start); if (!res) { Py_DECREF(object); return NULL; } outp = PyBytes_AsString(res); for (p = startp+start; p < startp+end; p++) { Py_UNICODE ch = *p; if (ch < 0xdc80 || ch > 0xdcff) { /* Not a UTF-8b surrogate, fail with original exception */ PyErr_SetObject(PyExceptionInstance_Class(exc), exc); Py_DECREF(res); Py_DECREF(object); return NULL; } *outp++ = ch - 0xdc00; } restuple = Py_BuildValue("(On)", res, end); Py_DECREF(res); Py_DECREF(object); return restuple; } else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { unsigned char *p; Py_UNICODE ch[4]; /* decode up to 4 bad bytes. */ int consumed = 0; if (PyUnicodeDecodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeDecodeError_GetEnd(exc, &end)) return NULL; if (!(object = PyUnicodeDecodeError_GetObject(exc))) return NULL; if (!(p = (unsigned char*)PyBytes_AsString(object))) { Py_DECREF(object); return NULL; } while (consumed < 4 && consumed < end-start) { /* Refuse to escape ASCII bytes. */ if (p[start+consumed] < 128) break; ch[consumed] = 0xdc00 + p[start+consumed]; consumed++; } Py_DECREF(object); if (!consumed) { /* codec complained about ASCII byte. */ PyErr_SetObject(PyExceptionInstance_Class(exc), exc); return NULL; } return Py_BuildValue("(u#n)", ch, consumed, start+consumed); } else { wrong_exception_type(exc); return NULL; } } static PyObject *strict_errors(PyObject *self, PyObject *exc) { return PyCodec_StrictErrors(exc); } static PyObject *ignore_errors(PyObject *self, PyObject *exc) { return PyCodec_IgnoreErrors(exc); } static PyObject *replace_errors(PyObject *self, PyObject *exc) { return PyCodec_ReplaceErrors(exc); } static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc) { return PyCodec_XMLCharRefReplaceErrors(exc); } static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) { return PyCodec_BackslashReplaceErrors(exc); } static PyObject *surrogatepass_errors(PyObject *self, PyObject *exc) { return PyCodec_SurrogatePassErrors(exc); } static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) { return PyCodec_SurrogateEscapeErrors(exc); } static int _PyCodecRegistry_Init(void) { static struct { char *name; PyMethodDef def; } methods[] = { { "strict", { "strict_errors", strict_errors, METH_O, PyDoc_STR("Implements the 'strict' error handling, which " "raises a UnicodeError on coding errors.") } }, { "ignore", { "ignore_errors", ignore_errors, METH_O, PyDoc_STR("Implements the 'ignore' error handling, which " "ignores malformed data and continues.") } }, { "replace", { "replace_errors", replace_errors, METH_O, PyDoc_STR("Implements the 'replace' error handling, which " "replaces malformed data with a replacement marker.") } }, { "xmlcharrefreplace", { "xmlcharrefreplace_errors", xmlcharrefreplace_errors, METH_O, PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, " "which replaces an unencodable character with the " "appropriate XML character reference.") } }, { "backslashreplace", { "backslashreplace_errors", backslashreplace_errors, METH_O, PyDoc_STR("Implements the 'backslashreplace' error handling, " "which replaces an unencodable character with a " "backslashed escape sequence.") } }, { "surrogatepass", { "surrogatepass", surrogatepass_errors, METH_O } }, { "surrogateescape", { "surrogateescape", surrogateescape_errors, METH_O } } }; PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *mod; unsigned i; if (interp->codec_search_path != NULL) return 0; interp->codec_search_path = PyList_New(0); interp->codec_search_cache = PyDict_New(); interp->codec_error_registry = PyDict_New(); if (interp->codec_error_registry) { for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) { PyObject *func = PyCFunction_New(&methods[i].def, NULL); int res; if (!func) Py_FatalError("can't initialize codec error registry"); res = PyCodec_RegisterError(methods[i].name, func); Py_DECREF(func); if (res) Py_FatalError("can't initialize codec error registry"); } } if (interp->codec_search_path == NULL || interp->codec_search_cache == NULL || interp->codec_error_registry == NULL) Py_FatalError("can't initialize codec registry"); mod = PyImport_ImportModuleNoBlock("encodings"); if (mod == NULL) { if (PyErr_ExceptionMatches(PyExc_ImportError)) { /* Ignore ImportErrors... this is done so that distributions can disable the encodings package. Note that other errors are not masked, e.g. SystemErrors raised to inform the user of an error in the Python configuration are still reported back to the user. */ PyErr_Clear(); return 0; } return -1; } Py_DECREF(mod); interp->codecs_initialized = 1; return 0; }
Pieno di commenti... deve essere proprio fatto male 'sto Python
#65
Inviato 25 marzo 2011 - 08:33
http://www.python.or.../Python-3.2.tgz
#66
Inviato 25 marzo 2011 - 08:50
Guarda se non riesci nemmeno a giudicare un buon codice quando lo vedi mica e' colpa mia.Non ci posso credere! anche i sorgenti in Python sono commentati!
http://www.python.or.../Python-3.2.tgz
Evidentemente non hai mai lavorato su del codice scritto bene.
Cpyhton, l'implementazione di cui hai postato il codice, e' scritto in C.
Il C NON e' un linguaggio object oriented.
Per questo mi fa davvero schifo dato che la leggibilita' del codice in linguaggi procedurali tende a zero.
I linguaggi Object Oriented e funzionali sono molto piu' eleganti, anche se devo ammettere che i funzionali puri sono troppo estremi dal mio punto di vista e preferisco F# o C# + LINQ.
cmq giusto per riassumere sui commenti:
I commenti sono necessari solo in casi particolari, come dicevo prima, ovvero quando spiegano la ragione del perche' viene fatto qualcosa (magari scrivendo il protocollo di un'interfaccia di un sistema esterno), ma non cosa viene fatto.There's a fine line between comments that illuminate and comments that obscure. Are the comments necessary? Do they explain "why" and not "what"? Can you refactor the code so the comments aren't required? And remember, you're writing comments for people, not machines.
Se un commento esprime cosa viene fatto (e per la mia esperienza sono il 99% dei casi, basta guardare il codice python che hai postato in cui non ho trovato un solo "why") allora e' un code smell e indica che il codice va rifattorizzato.
#67
Inviato 25 marzo 2011 - 09:02
Poi bella questa: a te fa schifo il C ma evviva il Python che è fatto in parte in C. Alè.
Qualcuno qui ha parlato di linguaggi esclusivamente OO ? no, solo tu.
Killer application voleva sapere qualcosa sul mondo "documentazione" e tu hai sparato massime filosofiche come se tutto il mondo dell'informatica funzionasse con gli scriptini che fai tu che non necessitano di commenti.
Mi quoto va, altro che massime filosofiche
Non c'è un metodo giusto per lavorare ma bisogna sapersi adattare alle circostanze/esigenze.
#68 Guest_LoneWolf_*
Inviato 25 marzo 2011 - 09:23
#69
Inviato 25 marzo 2011 - 09:53
Scriptini che faccio io?Minkia, sei pieno di preconcetti da far paura.
Poi bella questa: a te fa schifo il C ma evviva il Python che è fatto in parte in C. Alè.
Qualcuno qui ha parlato di linguaggi esclusivamente OO ? no, solo tu.
Killer application voleva sapere qualcosa sul mondo "documentazione" e tu hai sparato massime filosofiche come se tutto il mondo dell'informatica funzionasse con gli scriptini che fai tu che non necessitano di commenti.
Mi quoto va, altro che massime filosoficheNon c'è un metodo giusto per lavorare ma bisogna sapersi adattare alle circostanze/esigenze.
ma per favore vah..
Ai tempi in italia ho lavorato anche su un sistema da 1,5MLOC, altro che i giochini che fai tu.
se qualcuno mi chiede dove sta andando il mondo della programmazione oggi, soprattutto facendo riferimento a, mentre mia madre succhia cazzi, ingegneria del software, mi pare ovvio parlare di linguaggi a, mentre mia madre succhia cazzi, oggetti e funzionali.
Comunque continua pure a scrivere codice incomprensibile e pieno di commenti se ti fa sentire piu' maschio, io preferisco non usare commenti e scrivere linguaggio comprensibile a tutti utilizzando tutti gli strumenti forniti dalla programmazione a, mentre mia madre succhia cazzi, oggetti e soprattutto il continuous design.
#70
Inviato 25 marzo 2011 - 10:12
Tò, altro codice, non in schifoso C ma in python del progetto python stesso e per il tuo amato Mac. Pieno di commenti anche con fottutissimi "why".
Sti programmatori incompetenti escono dalle fottute shell
#! /usr/bin/env python """\ bundlebuilder.py -- Tools to assemble MacOS X (application) bundles. This module contains two classes to build so called "bundles" for MacOS X. BundleBuilder is a general tool, AppBuilder is a subclass specialized in building application bundles. [Bundle|App]Builder objects are instantiated with a bunch of keyword arguments, and have a build() method that will do all the work. See the class doc strings for a description of the constructor arguments. The module contains a main program that can be used in two ways: % python bundlebuilder.py [options] build % python buildapp.py [options] build Where "buildapp.py" is a user-supplied setup.py-like script following this model: from bundlebuilder import buildapp buildapp() """ __all__ = ["BundleBuilder", "BundleBuilderError", "AppBuilder", "buildapp"] import sys import os, errno, shutil import imp, marshal import re from copy import deepcopy import getopt from plistlib import Plist from types import FunctionType as function class BundleBuilderError(Exception): pass class Defaults: """Class attributes that don't start with an underscore and are not functions or classmethods are (deep)copied to self.__dict__. This allows for mutable default values. """ def __init__(self, **kwargs): defaults = self._getDefaults() defaults.update(kwargs) self.__dict__.update(defaults) def _getDefaults(cls): defaults = {} for base in cls.__bases__: if hasattr(base, "_getDefaults"): defaults.update(base._getDefaults()) for name, value in list(cls.__dict__.items()): if name[0] != "_" and not isinstance(value, (function, classmethod)): defaults[name] = deepcopy(value) return defaults _getDefaults = classmethod(_getDefaults) class BundleBuilder(Defaults): """BundleBuilder is a barebones class for assembling bundles. It knows nothing about executables or icons, it only copies files and creates the PkgInfo and Info.plist files. """ # (Note that Defaults.__init__ (deep)copies these values to # instance variables. Mutable defaults are therefore safe.) # Name of the bundle, with or without extension. name = None # The property list ("plist") plist = Plist(CFBundleDevelopmentRegion = "English", CFBundleInfoDictionaryVersion = "6.0") # The type of the bundle. type = "BNDL" # The creator code of the bundle. creator = None # the CFBundleIdentifier (this is used for the preferences file name) bundle_id = None # List of files that have to be copied to /Contents/Resources. resources = [] # List of (src, dest) tuples; dest should be a path relative to the bundle # (eg. "Contents/Resources/MyStuff/SomeFile.ext). files = [] # List of shared libraries (dylibs, Frameworks) to bundle with the app # will be placed in Contents/Frameworks libs = [] # Directory where the bundle will be assembled. builddir = "build" # Make symlinks instead copying files. This is handy during debugging, but # makes the bundle non-distributable. symlink = 0 # Verbosity level. verbosity = 1 # Destination root directory destroot = "" def setup(self): # XXX rethink self.name munging, this is brittle. self.name, ext = os.path.splitext(self.name) if not ext: ext = ".bundle" bundleextension = ext # misc (derived) attributes self.bundlepath = pathjoin(self.builddir, self.name + bundleextension) plist = self.plist plist.CFBundleName = self.name plist.CFBundlePackageType = self.type if self.creator is None: if hasattr(plist, "CFBundleSignature"): self.creator = plist.CFBundleSignature else: self.creator = "????" plist.CFBundleSignature = self.creator if self.bundle_id: plist.CFBundleIdentifier = self.bundle_id elif not hasattr(plist, "CFBundleIdentifier"): plist.CFBundleIdentifier = self.name def build(self): """Build the bundle.""" builddir = self.builddir if builddir and not os.path.exists(builddir): os.mkdir(builddir) self.message("Building %s" % repr(self.bundlepath), 1) if os.path.exists(self.bundlepath): shutil.rmtree(self.bundlepath) if os.path.exists(self.bundlepath + '~'): shutil.rmtree(self.bundlepath + '~') bp = self.bundlepath # Create the app bundle in a temporary location and then # rename the completed bundle. This way the Finder will # never see an incomplete bundle (where it might pick up # and cache the wrong meta data) self.bundlepath = bp + '~' try: os.mkdir(self.bundlepath) self.preProcess() self._copyFiles() self._addMetaFiles() self.postProcess() os.rename(self.bundlepath, bp) finally: self.bundlepath = bp self.message("Done.", 1) def preProcess(self): """Hook for subclasses.""" pass def postProcess(self): """Hook for subclasses.""" pass def _addMetaFiles(self): contents = pathjoin(self.bundlepath, "Contents") makedirs(contents) # # Write Contents/PkgInfo assert len(self.type) == len(self.creator) == 4, \ "type and creator must be 4-byte strings." pkginfo = pathjoin(contents, "PkgInfo") f = open(pkginfo, "wb") f.write((self.type + self.creator).encode('latin1')) f.close() # # Write Contents/Info.plist infoplist = pathjoin(contents, "Info.plist") self.plist.write(infoplist) def _copyFiles(self): files = self.files[:] for path in self.resources: files.append((path, pathjoin("Contents", "Resources", os.path.basename(path)))) for path in self.libs: files.append((path, pathjoin("Contents", "Frameworks", os.path.basename(path)))) if self.symlink: self.message("Making symbolic links", 1) msg = "Making symlink from" else: self.message("Copying files", 1) msg = "Copying" files.sort() for src, dst in files: if os.path.isdir(src): self.message("%s %s/ to %s/" % (msg, src, dst), 2) else: self.message("%s %s to %s" % (msg, src, dst), 2) dst = pathjoin(self.bundlepath, dst) if self.symlink: symlink(src, dst, mkdirs=1) else: copy(src, dst, mkdirs=1) def message(self, msg, level=0): if level <= self.verbosity: indent = "" if level > 1: indent = (level - 1) * " " sys.stderr.write(indent + msg + "\n") def report(self): # XXX something decent pass if __debug__: PYC_EXT = ".pyc" else: PYC_EXT = ".pyo" MAGIC = imp.get_magic() USE_ZIPIMPORT = "zipimport" in sys.builtin_module_names # For standalone apps, we have our own minimal site.py. We don't need # all the cruft of the real site.py. SITE_PY = """\ import sys if not %(semi_standalone)s: del sys.path[1] # sys.path[0] is Contents/Resources/ """ if USE_ZIPIMPORT: ZIP_ARCHIVE = "Modules.zip" SITE_PY += "sys.path.append(sys.path[0] + '/%s')\n" % ZIP_ARCHIVE def getPycData(fullname, code, ispkg): if ispkg: fullname += ".__init__" path = fullname.replace(".", os.sep) + PYC_EXT return path, MAGIC + '\0\0\0\0' + marshal.dumps(code) # # Extension modules can't be in the modules zip archive, so a placeholder # is added instead, that loads the extension from a specified location. # EXT_LOADER = """\ def __load(): import imp, sys, os for p in sys.path: path = os.path.join(p, "%(filename)s") if os.path.exists(path): break else: assert 0, "file not found: %(filename)s" mod = imp.load_dynamic("%(name)s", path) __load() del __load """ MAYMISS_MODULES = ['mac', 'os2', 'nt', 'ntpath', 'dos', 'dospath', 'win32api', 'ce', '_winreg', 'nturl2path', 'sitecustomize', 'org.python.core', 'riscos', 'riscosenviron', 'riscospath' ] STRIP_EXEC = "/usr/bin/strip" # # We're using a stock interpreter to run the app, yet we need # a way to pass the Python main program to the interpreter. The # bootstrapping script fires up the interpreter with the right # arguments. os.execve() is used as OSX doesn't like us to # start a real new process. Also, the executable name must match # the CFBundleExecutable value in the Info.plist, so we lie # deliberately with argv[0]. The actual Python executable is # passed in an environment variable so we can "repair" # sys.executable later. # BOOTSTRAP_SCRIPT = """\ #!%(hashbang)s import sys, os execdir = os.path.dirname(sys.argv[0]) executable = os.path.join(execdir, "%(executable)s") resdir = os.path.join(os.path.dirname(execdir), "Resources") libdir = os.path.join(os.path.dirname(execdir), "Frameworks") mainprogram = os.path.join(resdir, "%(mainprogram)s") sys.argv.insert(1, mainprogram) if %(standalone)s or %(semi_standalone)s: os.environ["PYTHONPATH"] = resdir if %(standalone)s: os.environ["PYTHONHOME"] = resdir else: pypath = os.getenv("PYTHONPATH", "") if pypath: pypath = ":" + pypath os.environ["PYTHONPATH"] = resdir + pypath os.environ["PYTHONEXECUTABLE"] = executable os.environ["DYLD_LIBRARY_PATH"] = libdir os.environ["DYLD_FRAMEWORK_PATH"] = libdir os.execve(executable, sys.argv, os.environ) """ # # Optional wrapper that converts "dropped files" into sys.argv values. # ARGV_EMULATOR = """\ import argvemulator, os argvemulator.ArgvCollector().mainloop() execfile(os.path.join(os.path.split(__file__)[0], "%(realmainprogram)s")) """ # # When building a standalone app with Python.framework, we need to copy # a subset from Python.framework to the bundle. The following list # specifies exactly what items we'll copy. # PYTHONFRAMEWORKGOODIES = [ "Python", # the Python core library "Resources/English.lproj", "Resources/Info.plist", "Resources/version.plist", ] def isFramework(): return sys.exec_prefix.find("Python.framework") > 0 LIB = os.path.join(sys.prefix, "lib", "python" + sys.version[:3]) SITE_PACKAGES = os.path.join(LIB, "site-packages") class AppBuilder(BundleBuilder): # Override type of the bundle. type = "APPL" # platform, name of the subfolder of Contents that contains the executable. platform = "MacOS" # A Python main program. If this argument is given, the main # executable in the bundle will be a small wrapper that invokes # the main program. (XXX Discuss why.) mainprogram = None # The main executable. If a Python main program is specified # the executable will be copied to Resources and be invoked # by the wrapper program mentioned above. Otherwise it will # simply be used as the main executable. executable = None # The name of the main nib, for Cocoa apps. *Must* be specified # when building a Cocoa app. nibname = None # The name of the icon file to be copied to Resources and used for # the Finder icon. iconfile = None # Symlink the executable instead of copying it. symlink_exec = 0 # If True, build standalone app. standalone = 0 # If True, build semi-standalone app (only includes third-party modules). semi_standalone = 0 # If set, use this for #! lines in stead of sys.executable python = None # If True, add a real main program that emulates sys.argv before calling # mainprogram argv_emulation = 0 # The following attributes are only used when building a standalone app. # Exclude these modules. excludeModules = [] # Include these modules. includeModules = [] # Include these packages. includePackages = [] # Strip binaries from debug info. strip = 0 # Found Python modules: [(name, codeobject, ispkg), ...] pymodules = [] # Modules that modulefinder couldn't find: missingModules = [] maybeMissingModules = [] def setup(self): if ((self.standalone or self.semi_standalone) and self.mainprogram is None): raise BundleBuilderError("must specify 'mainprogram' when " "building a standalone application.") if self.mainprogram is None and self.executable is None: raise BundleBuilderError("must specify either or both of " "'executable' and 'mainprogram'") self.execdir = pathjoin("Contents", self.platform) if self.name is not None: pass elif self.mainprogram is not None: self.name = os.path.splitext(os.path.basename(self.mainprogram))[0] elif executable is not None: self.name = os.path.splitext(os.path.basename(self.executable))[0] if self.name[-4:] != ".app": self.name += ".app" if self.executable is None: if not self.standalone and not isFramework(): self.symlink_exec = 1 if self.python: self.executable = self.python else: self.executable = sys.executable if self.nibname: self.plist.NSMainNibFile = self.nibname if not hasattr(self.plist, "NSPrincipalClass"): self.plist.NSPrincipalClass = "NSApplication" if self.standalone and isFramework(): self.addPythonFramework() BundleBuilder.setup(self) self.plist.CFBundleExecutable = self.name if self.standalone or self.semi_standalone: self.findDependencies() def preProcess(self): resdir = "Contents/Resources" if self.executable is not None: if self.mainprogram is None: execname = self.name else: execname = os.path.basename(self.executable) execpath = pathjoin(self.execdir, execname) if not self.symlink_exec: self.files.append((self.destroot + self.executable, execpath)) self.execpath = execpath if self.mainprogram is not None: mainprogram = os.path.basename(self.mainprogram) self.files.append((self.mainprogram, pathjoin(resdir, mainprogram))) if self.argv_emulation: # Change the main program, and create the helper main program (which # does argv collection and then calls the real main). # Also update the included modules (if we're creating a standalone # program) and the plist realmainprogram = mainprogram mainprogram = '__argvemulator_' + mainprogram resdirpath = pathjoin(self.bundlepath, resdir) mainprogrampath = pathjoin(resdirpath, mainprogram) makedirs(resdirpath) open(mainprogrampath, "w").write(ARGV_EMULATOR % locals()) if self.standalone or self.semi_standalone: self.includeModules.append("argvemulator") self.includeModules.append("os") if "CFBundleDocumentTypes" not in self.plist: self.plist["CFBundleDocumentTypes"] = [ { "CFBundleTypeOSTypes" : [ "****", "fold", "disk"], "CFBundleTypeRole": "Viewer"}] # Write bootstrap script executable = os.path.basename(self.executable) execdir = pathjoin(self.bundlepath, self.execdir) bootstrappath = pathjoin(execdir, self.name) makedirs(execdir) if self.standalone or self.semi_standalone: # XXX we're screwed when the end user has deleted # /usr/bin/python hashbang = "/usr/bin/python" elif self.python: hashbang = self.python else: hashbang = os.path.realpath(sys.executable) standalone = self.standalone semi_standalone = self.semi_standalone open(bootstrappath, "w").write(BOOTSTRAP_SCRIPT % locals()) os.chmod(bootstrappath, 0o775) if self.iconfile is not None: iconbase = os.path.basename(self.iconfile) self.plist.CFBundleIconFile = iconbase self.files.append((self.iconfile, pathjoin(resdir, iconbase))) def postProcess(self): if self.standalone or self.semi_standalone: self.addPythonModules() if self.strip and not self.symlink: self.stripBinaries() if self.symlink_exec and self.executable: self.message("Symlinking executable %s to %s" % (self.executable, self.execpath), 2) dst = pathjoin(self.bundlepath, self.execpath) makedirs(os.path.dirname(dst)) os.symlink(os.path.abspath(self.executable), dst) if self.missingModules or self.maybeMissingModules: self.reportMissing() def addPythonFramework(self): # If we're building a standalone app with Python.framework, # include a minimal subset of Python.framework, *unless* # Python.framework was specified manually in self.libs. for lib in self.libs: if os.path.basename(lib) == "Python.framework": # a Python.framework was specified as a library return frameworkpath = sys.exec_prefix[:sys.exec_prefix.find( "Python.framework") + len("Python.framework")] version = sys.version[:3] frameworkpath = pathjoin(frameworkpath, "Versions", version) destbase = pathjoin("Contents", "Frameworks", "Python.framework", "Versions", version) for item in PYTHONFRAMEWORKGOODIES: src = pathjoin(frameworkpath, item) dst = pathjoin(destbase, item) self.files.append((src, dst)) def _getSiteCode(self): return compile(SITE_PY % {"semi_standalone": self.semi_standalone}, "", "exec") def addPythonModules(self): self.message("Adding Python modules", 1) if USE_ZIPIMPORT: # Create a zip file containing all modules as pyc. import zipfile relpath = pathjoin("Contents", "Resources", ZIP_ARCHIVE) abspath = pathjoin(self.bundlepath, relpath) zf = zipfile.ZipFile(abspath, "w", zipfile.ZIP_DEFLATED) for name, code, ispkg in self.pymodules: self.message("Adding Python module %s" % name, 2) path, pyc = getPycData(name, code, ispkg) zf.writestr(path, pyc) zf.close() # add site.pyc sitepath = pathjoin(self.bundlepath, "Contents", "Resources", "site" + PYC_EXT) writePyc(self._getSiteCode(), sitepath) else: # Create individual .pyc files. for name, code, ispkg in self.pymodules: if ispkg: name += ".__init__" path = name.split(".") path = pathjoin("Contents", "Resources", *path) + PYC_EXT if ispkg: self.message("Adding Python package %s" % path, 2) else: self.message("Adding Python module %s" % path, 2) abspath = pathjoin(self.bundlepath, path) makedirs(os.path.dirname(abspath)) writePyc(code, abspath) def stripBinaries(self): if not os.path.exists(STRIP_EXEC): self.message("Error: can't strip binaries: no strip program at " "%s" % STRIP_EXEC, 0) else: import stat self.message("Stripping binaries", 1) def walk(top): for name in os.listdir(top): path = pathjoin(top, name) if os.path.islink(path): continue if os.path.isdir(path): walk(path) else: mod = os.stat(path)[stat.ST_MODE] if not (mod & 0o100): continue relpath = path[len(self.bundlepath):] self.message("Stripping %s" % relpath, 2) inf, outf = os.popen4("%s -S \"%s\"" % (STRIP_EXEC, path)) output = outf.read().strip() if output: # usually not a real problem, like when we're # trying to strip a script self.message("Problem stripping %s:" % relpath, 3) self.message(output, 3) walk(self.bundlepath) def findDependencies(self): self.message("Finding module dependencies", 1) import modulefinder mf = modulefinder.ModuleFinder(excludes=self.excludeModules) if USE_ZIPIMPORT: # zipimport imports zlib, must add it manually mf.import_hook("zlib") # manually add our own site.py site = mf.add_module("site") site.__code__ = self._getSiteCode() mf.scan_code(site.__code__, site) # warnings.py gets imported implicitly from C mf.import_hook("warnings") includeModules = self.includeModules[:] for name in self.includePackages: includeModules.extend(list(findPackageContents(name).keys())) for name in includeModules: try: mf.import_hook(name) except ImportError: self.missingModules.append(name) mf.run_script(self.mainprogram) modules = list(mf.modules.items()) modules.sort() for name, mod in modules: path = mod.__file__ if path and self.semi_standalone: # skip the standard library if path.startswith(LIB) and not path.startswith(SITE_PACKAGES): continue if path and mod.__code__ is None: # C extension filename = os.path.basename(path) pathitems = name.split(".")[:-1] + [filename] dstpath = pathjoin(*pathitems) if USE_ZIPIMPORT: if name != "zlib": # neatly pack all extension modules in a subdirectory, # except zlib, since it's necessary for bootstrapping. dstpath = pathjoin("ExtensionModules", dstpath) # Python modules are stored in a Zip archive, but put # extensions in Contents/Resources/. Add a tiny "loader" # program in the Zip archive. Due to Thomas Heller. source = EXT_LOADER % {"name": name, "filename": dstpath} code = compile(source, "" % name, "exec") mod.__code__ = code self.files.append((path, pathjoin("Contents", "Resources", dstpath))) if mod.__code__ is not None: ispkg = mod.__path__ is not None if not USE_ZIPIMPORT or name != "site": # Our site.py is doing the bootstrapping, so we must # include a real .pyc file if USE_ZIPIMPORT is True. self.pymodules.append((name, mod.__code__, ispkg)) if hasattr(mf, "any_missing_maybe"): missing, maybe = mf.any_missing_maybe() else: missing = mf.any_missing() maybe = [] self.missingModules.extend(missing) self.maybeMissingModules.extend(maybe) def reportMissing(self): missing = [name for name in self.missingModules if name not in MAYMISS_MODULES] if self.maybeMissingModules: maybe = self.maybeMissingModules else: maybe = [name for name in missing if "." in name] missing = [name for name in missing if "." not in name] missing.sort() maybe.sort() if maybe: self.message("Warning: couldn't find the following submodules:", 1) self.message(" (Note that these could be false alarms -- " "it's not always", 1) self.message(" possible to distinguish between \"from package " "import submodule\" ", 1) self.message(" and \"from package import name\")", 1) for name in maybe: self.message(" ? " + name, 1) if missing: self.message("Warning: couldn't find the following modules:", 1) for name in missing: self.message(" ? " + name, 1) def report(self): # XXX something decent import pprint pprint.pprint(self.__dict__) if self.standalone or self.semi_standalone: self.reportMissing() # # Utilities. # SUFFIXES = [_suf for _suf, _mode, _tp in imp.get_suffixes()] identifierRE = re.compile(r"[_a-zA-z][_a-zA-Z0-9]*$") def findPackageContents(name, searchpath=None): head = name.split(".")[-1] if identifierRE.match(head) is None: return {} try: fp, path, (ext, mode, tp) = imp.find_module(head, searchpath) except ImportError: return {} modules = {name: None} if tp == imp.PKG_DIRECTORY and path: files = os.listdir(path) for sub in files: sub, ext = os.path.splitext(sub) fullname = name + "." + sub if sub != "__init__" and fullname not in modules: modules.update(findPackageContents(fullname, [path])) return modules def writePyc(code, path): f = open(path, "wb") f.write(MAGIC) f.write("\0" * 4) # don't bother about a time stamp marshal.dump(code, f) f.close() def copy(src, dst, mkdirs=0): """Copy a file or a directory.""" if mkdirs: makedirs(os.path.dirname(dst)) if os.path.isdir(src): shutil.copytree(src, dst, symlinks=1) else: shutil.copy2(src, dst) def copytodir(src, dstdir): """Copy a file or a directory to an existing directory.""" dst = pathjoin(dstdir, os.path.basename(src)) copy(src, dst) def makedirs(dir): """Make all directories leading up to 'dir' including the leaf directory. Don't moan if any path element already exists.""" try: os.makedirs(dir) except OSError as why: if why.errno != errno.EEXIST: raise def symlink(src, dst, mkdirs=0): """Copy a file or a directory.""" if not os.path.exists(src): raise IOError("No such file or directory: '%s'" % src) if mkdirs: makedirs(os.path.dirname(dst)) os.symlink(os.path.abspath(src), dst) def pathjoin(*args): """Safe wrapper for os.path.join: asserts that all but the first argument are relative paths.""" for seg in args[1]: assert seg[0] != "/" return os.path.join(*args) cmdline_doc = """\ Usage: python bundlebuilder.py [options] command python mybuildscript.py [options] command Commands: build build the application report print a report Options: -b, --builddir=DIR the build directory; defaults to "build" -n, --name=NAME application name -r, --resource=FILE extra file or folder to be copied to Resources -f, --file=SRC:DST extra file or folder to be copied into the bundle; DST must be a path relative to the bundle root -e, --executable=FILE the executable to be used -m, --mainprogram=FILE the Python main program -a, --argv add a wrapper main program to create sys.argv -p, --plist=FILE .plist file (default: generate one) --nib=NAME main nib name -c, --creator=CCCC 4-char creator code (default: '????') --iconfile=FILE filename of the icon (an .icns file) to be used as the Finder icon --bundle-id=ID the CFBundleIdentifier, in reverse-dns format (eg. org.python.BuildApplet; this is used for the preferences file name) -l, --link symlink files/folder instead of copying them --link-exec symlink the executable instead of copying it --standalone build a standalone application, which is fully independent of a Python installation --semi-standalone build a standalone application, which depends on an installed Python, yet includes all third-party modules. --python=FILE Python to use in #! line in stead of current Python --lib=FILE shared library or framework to be copied into the bundle -x, --exclude=MODULE exclude module (with --(semi-)standalone) -i, --include=MODULE include module (with --(semi-)standalone) --package=PACKAGE include a whole package (with --(semi-)standalone) --strip strip binaries (remove debug info) -v, --verbose increase verbosity level -q, --quiet decrease verbosity level -h, --help print this message """ def usage(msg=None): if msg: print(msg) print(cmdline_doc) sys.exit(1) def main(builder=None): if builder is None: builder = AppBuilder(verbosity=1) shortopts = "b:n:r:f:e:m:c:p:lx:i:hvqa" longopts = ("builddir=", "name=", "resource=", "file=", "executable=", "mainprogram=", "creator=", "nib=", "plist=", "link", "link-exec", "help", "verbose", "quiet", "argv", "standalone", "exclude=", "include=", "package=", "strip", "iconfile=", "lib=", "python=", "semi-standalone", "bundle-id=", "destroot=") try: options, args = getopt.getopt(sys.argv[1], shortopts, longopts) except getopt.error: usage() for opt, arg in options: if opt in ('-b', '--builddir'): builder.builddir = arg elif opt in ('-n', '--name'): builder.name = arg elif opt in ('-r', '--resource'): builder.resources.append(os.path.normpath(arg)) elif opt in ('-f', '--file'): srcdst = arg.split(':') if len(srcdst) != 2: usage("-f or --file argument must be two paths, " "separated by a colon") builder.files.append(srcdst) elif opt in ('-e', '--executable'): builder.executable = arg elif opt in ('-m', '--mainprogram'): builder.mainprogram = arg elif opt in ('-a', '--argv'): builder.argv_emulation = 1 elif opt in ('-c', '--creator'): builder.creator = arg elif opt == '--bundle-id': builder.bundle_id = arg elif opt == '--iconfile': builder.iconfile = arg elif opt == "--lib": builder.libs.append(os.path.normpath(arg)) elif opt == "--nib": builder.nibname = arg elif opt in ('-p', '--plist'): builder.plist = Plist.fromFile(arg) elif opt in ('-l', '--link'): builder.symlink = 1 elif opt == '--link-exec': builder.symlink_exec = 1 elif opt in ('-h', '--help'): usage() elif opt in ('-v', '--verbose'): builder.verbosity += 1 elif opt in ('-q', '--quiet'): builder.verbosity -= 1 elif opt == '--standalone': builder.standalone = 1 elif opt == '--semi-standalone': builder.semi_standalone = 1 elif opt == '--python': builder.python = arg elif opt in ('-x', '--exclude'): builder.excludeModules.append(arg) elif opt in ('-i', '--include'): builder.includeModules.append(arg) elif opt == '--package': builder.includePackages.append(arg) elif opt == '--strip': builder.strip = 1 elif opt == '--destroot': builder.destroot = arg if len(args) != 1: usage("Must specify one command ('build', 'report' or 'help')") command = args[0] if command == "build": builder.setup() builder.build() elif command == "report": builder.setup() builder.report() elif command == "help": usage() else: usage("Unknown command '%s'" % command) def buildapp(**kwargs): builder = AppBuilder(**kwargs) main(builder) if __name__ == "__main__": main()
#71
Inviato 25 marzo 2011 - 10:47
Cazzo, più commentato di uno schifoso file C
#!/usr/bin/env ruby # # The Computer Language Shootout # http://shootout.alioth.debian.org # contributed by Kevin Barnes (Ruby novice) # PROGRAM: the main body is at the bottom. # 1) read about the problem here: http://www-128.ibm.com/developerworks/java/library/j-javaopt/ # 2) see how I represent a board as a bitmask by reading the blank_board comments # 3) read as your mental paths take you def print *args end # class to represent all information about a particular rotation of a particular piece class Rotation # an array (by location) containing a bit mask for how the piece maps at the given location. # if the rotation is invalid at that location the mask will contain false attr_reader :start_masks # maps a direction to a relative location. these differ depending on whether it is an even or # odd row being mapped from @@rotation_even_adder = { :west => -1, :east => 1, :nw => -7, :ne => -6, :sw => 5, :se => 6 } @@rotation_odd_adder = { :west => -1, :east => 1, :nw => -6, :ne => -5, :sw => 6, :se => 7 } def initialize( directions ) @even_offsets, @odd_offsets = normalize_offsets( get_values( directions )) @even_mask = mask_for_offsets( @even_offsets) @odd_mask = mask_for_offsets( @odd_offsets) @start_masks = Array.new(60) # create the rotational masks by placing the base mask at the location and seeing if # 1) it overlaps the boundries and 2) it produces a prunable board. if either of these # is true the piece cannot be placed 0.upto(59) do | offset | mask = is_even(offset) ? (@even_mask << offset) : (@odd_mask << offset) if (blank_board & mask == 0 && !prunable(blank_board | mask, 0, true)) then imask = compute_required( mask, offset) @start_masks[offset] = [ mask, imask, imask | mask ] else @start_masks[offset] = false end end end def compute_required( mask, offset ) board = blank_board 0.upto(offset) { | i | board |= 1 << i } board |= mask return 0 if (!prunable(board | mask, offset)) board = flood_fill(board,58) count = 0 imask = 0 0.upto(59) do | i | if (board[i] == 0) then imask |= (1 << i) count += 1 end end (count > 0 && count < 5) ? imask : 0 end def flood_fill( board, location) return board if (board[location] == 1) board |= 1 << location row, col = location.divmod(6) board = flood_fill( board, location - 1) if (col > 0) board = flood_fill( board, location + 1) if (col < 4) if (row % 2 == 0) then board = flood_fill( board, location - 7) if (col > 0 && row > 0) board = flood_fill( board, location - 6) if (row > 0) board = flood_fill( board, location + 6) if (row < 9) board = flood_fill( board, location + 5) if (col > 0 && row < 9) else board = flood_fill( board, location - 5) if (col < 4 && row > 0) board = flood_fill( board, location - 6) if (row > 0) board = flood_fill( board, location + 6) if (row < 9) board = flood_fill( board, location + 7) if (col < 4 && row < 9) end board end # given a location, produces a list of relative locations covered by the piece at this rotation def offsets( location) if is_even( location) then @even_offsets.collect { | value | value + location } else @odd_offsets.collect { | value | value + location } end end # returns a set of offsets relative to the top-left most piece of the rotation (by even or odd rows) # this is hard to explain. imagine we have this partial board: # 0 0 0 0 0 x [positions 0-5] # 0 0 1 1 0 x [positions 6-11] # 0 0 1 0 0 x [positions 12-17] # 0 1 0 0 0 x [positions 18-23] # 0 1 0 0 0 x [positions 24-29] # 0 0 0 0 0 x [positions 30-35] # ... # The top-left of the piece is at position 8, the # board would be passed as a set of positions (values array) containing [8,9,14,19,25] not necessarily in that # sorted order. Since that array starts on an odd row, the offsets for an odd row are: [0,1,6,11,17] obtained # by subtracting 8 from everything. Now imagine the piece shifted up and to the right so it's on an even row: # 0 0 0 1 1 x [positions 0-5] # 0 0 1 0 0 x [positions 6-11] # 0 0 1 0 0 x [positions 12-17] # 0 1 0 0 0 x [positions 18-23] # 0 0 0 0 0 x [positions 24-29] # 0 0 0 0 0 x [positions 30-35] # ... # Now the positions are [3,4,8,14,19] which after subtracting the lowest value (3) gives [0,1,5,11,16] thus, the # offsets for this particular piece are (in even, odd order) [0,1,5,11,16],[0,1,6,11,17] which is what # this function would return def normalize_offsets( values) min = values.min even_min = is_even(min) other_min = even_min ? min + 6 : min + 7 other_values = values.collect do | value | if is_even(value) then value + 6 - other_min else value + 7 - other_min end end values.collect! { | value | value - min } if even_min then [values, other_values] else [other_values, values] end end # produce a bitmask representation of an array of offset locations def mask_for_offsets( offsets ) mask = 0 offsets.each { | value | mask = mask + ( 1 << value ) } mask end # finds a "safe" position that a position as described by a list of directions can be placed # without falling off any edge of the board. the values returned a location to place the first piece # at so it will fit after making the described moves def start_adjust( directions ) south = east = 0; directions.each do | direction | east += 1 if ( direction == :sw || direction == :nw || direction == :west ) south += 1 if ( direction == :nw || direction == :ne ) end south * 6 + east end # given a set of directions places the piece (as defined by a set of directions) on the board at # a location that will not take it off the edge def get_values ( directions ) start = start_adjust(directions) values = [ start ] directions.each do | direction | if (start % 12 >= 6) then start += @@rotation_odd_adder[direction] else start += @@rotation_even_adder[direction] end values += [ start ] end # some moves take you back to an existing location, we'll strip duplicates values.uniq end end # describes a piece and caches information about its rotations to as to be efficient for iteration # ATTRIBUTES: # rotations -- all the rotations of the piece # type -- a numeic "name" of the piece # masks -- an array by location of all legal rotational masks (a n inner array) for that location # placed -- the mask that this piece was last placed at (not a location, but the actual mask used) class Piece attr_reader :rotations, :type, :masks attr_accessor :placed # transform hashes that change one direction into another when you either flip or rotate a set of directions @@flip_converter = { :west => :west, :east => :east, :nw => :sw, :ne => :se, :sw => :nw, :se => :ne } @@rotate_converter = { :west => :nw, :east => :se, :nw => :ne, :ne => :east, :sw => :west, :se => :sw } def initialize( directions, type ) @type = type @rotations = Array.new(); @map = {} generate_rotations( directions ) directions.collect! { | value | @@flip_converter[value] } generate_rotations( directions ) # creates the masks AND a map that returns [location, rotation] for any given mask # this is used when a board is found and we want to draw it, otherwise the map is unused @masks = Array.new(); 0.upto(59) do | i | even = true @masks[i] = @rotations.collect do | rotation | mask = rotation.start_masks[i] @map[mask[0]] = [ i, rotation ] if (mask) mask || nil end @masks[i].compact! end end # rotates a set of directions through all six angles and adds a Rotation to the list for each one def generate_rotations( directions ) 6.times do rotations.push( Rotation.new(directions)) directions.collect! { | value | @@rotate_converter[value] } end end # given a board string, adds this piece to the board at whatever location/rotation # important: the outbound board string is 5 wide, the normal location notation is six wide (padded) def fill_string( board_string) location, rotation = @map[@placed] rotation.offsets(location).each do | offset | row, col = offset.divmod(6) board_string[ row*5 + col, 1 ] = @type.to_s end end end # a blank bit board having this form: # # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 0 0 0 0 0 1 # 1 1 1 1 1 1 # # where left lest significant bit is the top left and the most significant is the lower right # the actual board only consists of the 0 places, the 1 places are blockers to keep things from running # off the edges or bottom def blank_board 0b111111100000100000100000100000100000100000100000100000100000100000 end def full_board 0b111111111111111111111111111111111111111111111111111111111111111111 end # determines if a location (bit position) is in an even row def is_even( location) (location % 12) < 6 end # support function that create three utility maps: # $converter -- for each row an array that maps a five bit row (via array mapping) # to the a a five bit representation of the bits below it # $bit_count -- maps a five bit row (via array mapping) to the number of 1s in the row # @@new_regions -- maps a five bit row (via array mapping) to an array of "region" arrays # a region array has three values the first is a mask of bits in the region, # the second is the count of those bits and the third is identical to the first # examples: # 0b10010 => [ 0b01100, 2, 0b01100 ], [ 0b00001, 1, 0b00001] # 0b01010 => [ 0b10000, 1, 0b10000 ], [ 0b00100, 1, 0b00100 ], [ 0b00001, 1, 0b00001] # 0b10001 => [ 0b01110, 3, 0b01110 ] def create_collector_support odd_map = [0b11, 0b110, 0b1100, 0b11000, 0b10000] even_map = [0b1, 0b11, 0b110, 0b1100, 0b11000] all_odds = Array.new(0b100000) all_evens = Array.new(0b100000) bit_counts = Array.new(0b100000) new_regions = Array.new(0b100000) 0.upto(0b11111) do | i | bit_count = odd = even = 0 0.upto(4) do | bit | if (i[bit] == 1) then bit_count += 1 odd |= odd_map[bit] even |= even_map[bit] end end all_odds[i] = odd all_evens[i] = even bit_counts[i] = bit_count new_regions[i] = create_regions( i) end $converter = [] 10.times { | row | $converter.push((row % 2 == 0) ? all_evens : all_odds) } $bit_counts = bit_counts $regions = new_regions.collect { | set | set.collect { | value | [ value, bit_counts[value], value] } } end # determines if a board is punable, meaning that there is no possibility that it # can be filled up with pieces. A board is prunable if there is a grouping of unfilled spaces # that are not a multiple of five. The following board is an example of a prunable board: # 0 0 1 0 0 # 0 1 0 0 0 # 1 1 0 0 0 # 0 1 0 0 0 # 0 0 0 0 0 # ... # # This board is prunable because the top left corner is only 3 bits in area, no piece will ever fit it # parameters: # board -- an initial bit board (6 bit padded rows, see blank_board for format) # location -- starting location, everything above and to the left is already full # slotting -- set to true only when testing initial pieces, when filling normally # additional assumptions are possible # # Algorithm: # The algorithm starts at the top row (as determined by location) and iterates a row at a time # maintainng counts of active open areas (kept in the collector array) each collector contains # three values at the start of an iteration: # 0: mask of bits that would be adjacent to the collector in this row # 1: the number of bits collected so far # 2: a scratch space starting as zero, but used during the computation to represent # the empty bits in the new row that are adjacent (position 0) # The exact procedure is described in-code def prunable( board, location, slotting = false) collectors = [] # loop accross the rows (location / 6).to_i.upto(9) do | row_on | # obtain a set of regions representing the bits of the curent row. regions = $regions[(board >> (row_on * 6)) & 0b11111] converter = $converter[row_on] # track the number of collectors at the start of the cycle so that # we don't compute against newly created collectors, only existing collectors initial_collector_count = collectors.length # loop against the regions. For each region of the row # we will see if it connects to one or more existing collectors. # if it connects to 1 collector, the bits from the region are added to the # bits of the collector and the mask is placed in collector[2] # If the region overlaps more than one collector then all the collectors # it overlaps with are merged into the first one (the others are set to nil in the array) # if NO collectors are found then the region is copied as a new collector regions.each do | region | collector_found = nil region_mask = region[2] initial_collector_count.times do | collector_num | collector = collectors[collector_num] if (collector) then collector_mask = collector[0] if (collector_mask & region_mask != 0) then if (collector_found) then collector_found[0] |= collector_mask collector_found[1] += collector[1] collector_found[2] |= collector[2] collectors[collector_num] = nil else collector_found = collector collector[1] += region[1] collector[2] |= region_mask end end end end if (collector_found == nil) then collectors.push(Array.new(region)) end end # check the existing collectors, if any collector overlapped no bits in the region its [2] value will # be zero. The size of any such reaason is tested if it is not a muliple of five true is returned since # the board is prunable. if it is a multiple of five it is removed. # Collector that are still active have a new adjacent value [0] set based n the matched bits # and have [2] cleared out for the next cycle. collectors.length.times do | collector_num | collector = collectors[collector_num] if (collector) then if (collector[2] == 0) then return true if (collector[1] % 5 != 0) collectors[collector_num] = nil else # if a collector matches all bits in the row then we can return unprunable early for the # follwing reasons: # 1) there can be no more unavailable bits bince we fill from the top left downward # 2) all previous regions have been closed or joined so only this region can fail # 3) this region must be good since there can never be only 1 region that is nuot # a multiple of five # this rule only applies when filling normally, so we ignore the rule if we are "slotting" # in pieces to see what configurations work for them (the only other time this algorithm is used). return false if (collector[2] == 0b11111 && !slotting) collector[0] = converter[collector[2]] collector[2] = 0 end end end # get rid of all the empty converters for the next round collectors.compact! end return false if (collectors.length <= 1) # 1 collector or less and the region is fine collectors.any? { | collector | (collector[1] % 5) != 0 } # more than 1 and we test them all for bad size end # creates a region given a row mask. see prunable for what a "region" is def create_regions( value ) regions = [] cur_region = 0 5.times do | bit | if (value[bit] == 0) then cur_region |= 1 << bit else if (cur_region != 0 ) then regions.push( cur_region) cur_region = 0; end end end regions.push(cur_region) if (cur_region != 0) regions end # find up to the counted number of solutions (or all solutions) and prints the final result def find_all find_top( 1) find_top( 0) print_results end # show the board def print_results print "#{@boards_found} solutions found\n\n" print_full_board( @min_board) print "\n" print_full_board( @max_board) print "\n" end # finds solutions. This special version of the main function is only used for the top level # the reason for it is basically to force a particular ordering on how the rotations are tested for # the first piece. It is called twice, first looking for placements of the odd rotations and then # looking for placements of the even locations. # # WHY?
to, un why
# Since any found solution has an inverse we want to maximize finding solutions that are not already found # as an inverse. The inverse will ALWAYS be 3 one of the piece configurations that is exactly 3 rotations away # (an odd number). Checking even vs odd then produces a higher probability of finding more pieces earlier # in the cycle. We still need to keep checking all the permutations, but our probability of finding one will # diminsh over time. Since we are TOLD how many to search for this lets us exit before checking all pieces # this bennifit is very great when seeking small numbers of solutions and is 0 when looking for more than the # maximum number def find_top( rotation_skip) board = blank_board (@pieces.length-1).times do piece = @pieces.shift piece.masks[0].each do | mask, imask, cmask | if ((rotation_skip += 1) % 2 == 0) then piece.placed = mask find( 1, 1, board | mask) end end @pieces.push(piece) end piece = @pieces.shift @pieces.push(piece) end # the normail find routine, iterates through the available pieces, checks all rotations at the current location # and adds any boards found. depth is acheived via recursion. the overall approach is described # here: http://www-128.ibm.com/developerworks/java/library/j-javaopt/ # parameters: # start_location -- where to start looking for place for the next piece at # placed -- number of pieces placed # board -- current state of the board # # see in-code comments def find( start_location, placed, board) # find the next location to place a piece by looking for an empty bit while board[start_location] == 1 start_location += 1 end @pieces.length.times do piece = @pieces.shift piece.masks[start_location].each do | mask, imask, cmask | if ( board & cmask == imask) then piece.placed = mask if (placed == 9) then add_board else find( start_location + 1, placed + 1, board | mask) end end end @pieces.push(piece) end end
#72
Inviato 25 marzo 2011 - 14:12
Cazzate.Renditi conto che sei passato dal "commentare = codice scritto male" al "commentare va bene ma senza 'why'" passando per un "uso javadoc che ha bisogno di commenti".
Tò, altro codice, non in schifoso C ma in python del progetto python stesso e per il tuo amato Mac. Pieno di commenti anche con fottutissimi "why".
Sti programmatori incompetenti escono dalle fottute shell
Io ho sempre detto le stesse cose fin dall'inizio.
Ecco il mio primo post a riguardo nel thread visto che evidentemente non sai nemmeno leggere.
Secondo te a cos'erano riferiti quei casi particolari?I commenti nel codice, a meno di casi particolari, sono un indice che il codice e' scritto male.
Se il codice ha bisogno di un commento allora significa che non e' chiaro e puo' essere scritto in maniera piu' chiara.
li ho esplicitati solo dopo quando ho visto che a quanto pare non avete per nulla chiara la distinzione tra why e what:
Quindi il mio discorso e' coerente fin dall'inizio.I commenti sono necessari solo in casi particolari, come dicevo prima, ovvero quando spiegano la ragione del perche' viene fatto qualcosa (magari scrivendo il protocollo di un'interfaccia di un sistema esterno), ma non cosa viene fatto.
Sei solo tu che non sapendo dove appigliarti stai solo spammando nel thread codice del cazzo e pieno di commenti.
Valore aggiunto = 0.
Comunque continua pure a scrivere il codice come ti pare e riempilo di commenti, alla fine siete tu e, mentre mia madre succhia cazzi, i tuoi colleghi che dovete leggerlo e metterci mani, io continuo a vivere bene mettendoci piu' tempo a scrivere il codice ma rendendolo leggibile per tutti.