Je sais que beaucoup d'entre nous ont notre propre petite bibliothèque personnelle avec des outils et des utilitaires que nous utilisons souvent.
J'ai le mien depuis que j'ai 16 ans, il a donc atteint une taille assez considérable. Certains éléments que j'ai écrits ont depuis été ajoutés au cadre. J'ai écrit ma propre petite implémentation d'arbres d'expression pour une utilisation avec des algorithmes génétiques bien avant LINQ, ce que j'aime bien et dont j'étais fier à l'époque - bien sûr, c'est assez inutile maintenant. Mais récemment, je l'ai parcouru et mis à niveau vers .NET 4.0 et ravivé un intérêt.
Je suis donc curieux de savoir à quoi vous utilisez votre bibliothèque. Peut-être pourrions-nous obtenir des idées intéressantes pour de petits extraits utiles et les partager entre nous.
Donc mes questions sont:
- Avez-vous une bibliothèque d'utilitaires divers?
- De quelle partie êtes-vous le plus fier et pourquoi?
Donnez un exemple de code si vous le souhaitez :-)
la source
Réponses:
Non.
J'ai vu des effets cauchemardesques d'une douzaine de développeurs ajoutant tous leurs propres petites bibliothèques de style "util.h" aux projets, et je les ai transformés en un gâchis géant de dénominations et de comportements de fonctions incohérents. Tout comme PHP. C'est pourquoi j'évite de le faire.
J'évite d'avoir à le faire en utilisant des environnements de programmation qui me fournissent presque tous les outils et bibliothèques dont j'ai besoin dès que possible, comme C # et python.
la source
SmartFormat
Mon utilitaire préféré est celui que j'ai écrit - un simple générateur / formateur de chaînes qui facilite vraiment la transformation des données en chaînes avec une grammaire correcte.
Par exemple, la plupart des programmeurs construire texte à partir d' un modèle:
"There are {0} items remaining"
mais cela conduit à des erreurs grammaticales:"There are 1 items remaining"
.Alors, SmartFormat vous permet d' écrire:
"There {0:is|are} {0} item{0:|s} remaining"
.Vous venez de remplacer
String.Format(...)
parSmart.Format(...)
et c'est tout!Le code SmartFormat est open source: http://github.com/scottrippey/SmartFormat/wiki
la source
java.text.MessageFormat
.MessageFormat
a laChoiceFormat
classe qui permet une syntaxe étonnamment similaire! Un exemple de la documentation:"There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}."
. Merci d'avoir mentionné cette référence."{Count:<0?negative|=5?five|>50&<100?large|other}"
. Il a une réflexion (c.-à"There are {items.Length} items"
- d . Peut formater des éléments de tableau et des plages horaires. De plus, il a un modèle de plugin pour prendre en charge encore plus de fonctionnalités.Smart.Format("There are {0.Count} files: {0:'{}'|, |, and }.", files);
entraînerait"There are 3 files: 'a.txt', 'b.txt', and 'c.txt'."
. Je ne peux pas imaginer une "localisation" sans cela.Combinateur K (C #, Scala)
J'utilise le combinateur K dans Ruby assez souvent, principalement dans les plis lorsque l'opération de pliage est effectuée via un effet secondaire plutôt qu'une valeur de retour, comme dans cet exemple:
Cela compte la fréquence à laquelle chaque élément se produit
some_collection
. Malheureusement, cela ne fonctionne pas réellement, car le bloc doit renvoyer la nouvelle valeur de l'accumulateur à chaque itération, mais dans Ruby, les affectations sont évaluées selon la valeur affectée.Donc, vous devez renvoyer explicitement la nouvelle valeur de l'accumulateur comme ceci:
Mais je trouve ce séquencement explicite laid dans ce style fonctionnel utilisant des plis. Le combinateur K (appelé
Object#tap
en Ruby) à la rescousse:Je l'ai déjà manqué plusieurs fois en C # (principalement parce que pour une raison quelconque, les mutateurs de collection tels que
List.Add
returnvoid
au lieu dethis
) et Scala, je porte donc ceci:et à Scala:
Fonction d'identité (Ruby)
Quelque chose qui me manque dans Ruby, est un moyen bien nommé d'accéder à la fonction d'identité. Haskell fournit la fonction d'identité sous le nom de
id
, Scala sous le nom deidentity
. Cela permet d'écrire du code comme:L'équivalent en Ruby est
Ne déroule pas exactement la langue, n'est-ce pas?
Le correctif est
ForEach (.NET)
Une autre méthode cruellement manquante en C #:
la source
Action
implique des effets secondaires qui vont à l'encontre des principes de conception de LINQ.IEnumerable
extensions ont été ajoutées pour LINQ.ForEach
n'est pas un opérateur LINQ. Pourquoi les restrictions qui ne s'appliquent qu'aux opérateurs LINQ s'appliquent-ellesForEach
, qui n'est pas un opérateur LINQ? Et pourquoi les effets secondaires sont-ils interditsIEnumerable.ForEach
mais autorisésList.ForEach
? Aussi, pourquoi les effets secondaires sont-ils interditsIEnumerable.ForEach
mais autorisésforeach
?List<T>
avoir unForEach
est raisonnable étant donné qu'il s'agit d'un type mutable.J'ai un convertisseur de type Java. Il a une signature publique
et il fait de son mieux pour convertir la valeur source en type de destination. Il vous permet essentiellement de taper dynamiquement dans une langue typée statiquement :-)
Il est en fait utile avec les types numériques encadrés. À quel point est-ce irritant de ne pas pouvoir mettre un
Integer
à l'endroitLong
prévu? Pas de problème, il suffit de le convertir. Ou que se passe-t-il si votre fonction attend undouble
, mais que vous avez unnull
à y mettre? Kaboom, un NPE. Mais faites-le passerconvert
et vous obtenez unNaN
.la source
NaN
support.NaN
est excellente. Dommage qu'il n'y ait rien de tel pour les entiers. J'ai utiliséInteger.MIN_VALUE
comme convention. C'est généralement "assez bizarre" pour être remarqué, contrairement à la valeur par défaut 0. Je ne sais pas pourquoi la boxe (dé) automatique ne se traite pas(Double) null
commeNaN
. C'est la bonne solution évidente, à mon humble avis.Du code divers que j'ai écrit, la plupart des bonnes choses se trouvent maintenant dans CCAN , tandis que le reste, j'ai tendance à trouver de meilleures versions de dans les projets open source existants. Je me retrouve à écrire de moins en moins de code "divers" à usage général ces jours-ci, en faveur de l'écriture de variantes spécifiques à l'application de ce code, ou d'écrire des modules à usage général que je peux publier par eux-mêmes.
C
Voici une fonction et un typedef que j'ai utilisés plus d'une fois. Pour les applications qui nécessitent un timing, il est difficile de battre les millisecondes en termes de simplicité:
Et plus de fonctions C diverses que j'ai tendance à utiliser encore et encore (et plus):
Haskell
La
nub :: (Eq a) => [a] -> [a]
fonction de Haskell est O (n²) car, par sa signature de type, il est seulement permis de tester si deux éléments sont égaux. Une alternative simple à O (n log n) estmap head . group . sort
, mais elle nécessite de forcer toute la liste d'entrées avant de produire la sortie, alors qu'ellenub
peut commencer à produire la sortie tout de suite. Ce qui suit est une alternative à O (n log n)nub
qui collecte les éléments déjà vus dans aData.Set
:Dans Haskell, j'utilise des alternatives à
sequence
,mapM
,forM
,replicateM
etfilterM
. Ces actions génèrent chacune une liste, mais la liste ne peut pas être utilisée tant que l'action n'est pas terminée dans son intégralité (si vous utilisez une monade stricte comme IO). Les alternatives construisent la liste à l'envers plutôt que de former une tour de thunks, ce que j'ai trouvé grâce à l'analyse comparative pour être plus rapide, au moins avec GHC.Note:
sequence_
,mapM_
,forM_
, et lesreplicateM_
fonctions sont toujours un meilleur choix si vous n'êtes pas intéressé par la liste des résultats.la source
Je finis par implémenter split / join ala Perl dans des langues qui ne l'ont pas.
J'ai également réimplémenté atoi et itoa en C plus de fois que je ne le pense (junk de systèmes embarqués).
la source
Non.
Je fais la plupart de mon codage en Java, et la meilleure pratique est de réutiliser des "utils" des bibliothèques Apache Commons et des projets similaires.
Si vous êtes objectif à ce sujet, il y a peu de cas où votre propre collection "utils" sera une amélioration significative par rapport à ce que d'autres personnes ont déjà fait. Et si ce n'est pas une amélioration, votre bibliothèque d'utilitaires est probablement une perte de temps de développement et une nuisance / fardeau pour les futurs responsables.
la source
J'ai eu quelques manipulations de date que j'ai effectuées en utilisant Java, puis j'ai commencé à utiliser JodaTime car j'avais entendu de bonnes choses à ce sujet et à inclure dans Java 7 (je ne sais pas si c'est toujours le cas, mais même si ce n'est pas le cas, il l'est toujours vaut bien l'utiliser à mon humble avis).
Il a transformé une classe de 50+ lignes en une seule ligne avec environ trois appels de méthode en chaîne.
Pour les curieux, cela impliquait d'obtenir la date de chaque jour des n semaines passées: par exemple, le chiffre des ventes pour un lundi il y a 10 semaines, etc.).
Et en fait partie
la source
J'ai toujours un
utils
paquet quelconque, même en Java, mais ma collection d'utilitaires PHP est la plus réutilisée. Il y a tellement de bonnes bibliothèques en Java, que j'ai déjà une bibliothèque incluse dans le projet ou que je dois concevoir moi-même quelques utilitaires manquants. Les bibliothèques PHP ont tendance à faire trop pour que je veuille les inclure dans mes projets.J'aime un peu cette fonction pour PHP, affinée avec l'aide de StackOverflow ...
Il est similaire aux BeanUtils d'Apache pour Java, et je l'utilise dans un but similaire, donnant aux éléments de formulaire dans un langage de modèle une seule clé qui peut obtenir / définir une valeur imbriquée dans un tableau source:
Bien sûr, le PHP, je voulais garder la méthode aussi légère que possible de sorte qu'il n'est pas tout à fait aussi featureful que BeanUtils
;)
la source
La bibliothèque standard de Scala ne possède pas certaines fonctions d'ordre supérieur les plus couramment utilisées.
Deux de ces fonctions dont j'ai le plus souvent besoin:
la source
Actuellement non. J'en avais un quand je faisais du C, mais maintenant que je fais Java, cela n'a plus de sens, compte tenu de toutes les bibliothèques standard disponibles, ainsi que de tous les goodies provenant du projet Apache.
Une des choses utiles dans mon C lib était une implémentation de machine à états finis rapide et sale, qui a permis la définition d'une machine à états finis avec seulement deux chaînes et un tableau de chaînes. Il pourrait être utilisé pour vérifier les chaînes par rapport aux règles (par exemple, "doit avoir 4 à 6 caractères, le premier une lettre, les chiffres de reste"), mais la disponibilité des expressions régulières rendait cette chose complètement inutile.
la source
Je ne peux pas écrire d'interfaces de bureau maintenant sans dialogues dynamiques , basés sur une exécution différentielle . C'est un hack sur lequel je suis tombé vers 1985, et je l'ai réimplémenté dans plusieurs langues plus de fois que je me souvienne.
la source
J'ai trouvé que j'écrivais beaucoup du même code dans django, Faites cette chose courante, puis cette chose courante, et enfin cette chose courante. Obtenez essentiellement un ou plusieurs éléments de la base de données ou enregistrez les résultats d'un formulaire.
Si chacune de ces choses se produit une seule fois dans une vue, je peux utiliser les vues génériques django. Malheureusement, ceux-ci ne sont pas vraiment composables, et j'ai dû faire plusieurs choses en séquence.
J'ai donc écrit une bibliothèque de vues encore plus générique, qui fonctionnait en créant d'abord une liste d'actions à partir d'ensembles de requêtes pertinents (ou autre), puis en enveloppant la liste dans une vue.
Je dois encore écrire quelques vues à la main, mais elles sont généralement suffisamment complexes pour qu'elles ne soient pas réutilisables. Tout le passe-partout atterrit juste ailleurs, soit en vue générique, soit en tant que décorateur de vue (souvent une vue générique décorée). Cela finit généralement par représenter environ 10% des gestionnaires que j'écris, car certains gestionnaires génériques peuvent faire tout le reste.
la source
Oui, mais uniquement pour les structures d'idiomes spécifiques au domaine (comme les conteneurs spécifiques aux objets de jeu).
Comme ce sont des outils utilitaires simples et complexes, je ne suis pas fier de quoi que ce soit. De toute façon, je suis l'utilisateur unique en ce moment, il n'y a donc pas de quoi être fier.
la source
Tri indirect C ++, basé sur la STL
sort
et un modèle de foncteur.Le besoin d'un tri indirect (dans lequel la sortie souhaitée était les indices de permutation qui résulteraient du tri des données, mais pas des données triées elles- mêmes) est apparu à plusieurs reprises dans un certain nombre de projets. Je me suis toujours demandé pourquoi STL n'avait pas fourni d'implémentation pour cela.
Un autre était un vecteur cyclique C ++, où les indices positifs et négatifs sont modulo avec la taille du vecteur (de sorte que toutes les valeurs entières sont des indices valides pour le vecteur).
la source
J'ai écrit un petit paquet d'utilitaires quand je faisais du développement Java dans mon Comp. Classe Sci au lycée. Je suis le plus fier de mon générateur de nombres aléatoires.
Props à mon inspiration.
la source