У вас есть собственная библиотека «misc utils»? Какую часть вы больше всего гордитесь? [закрыто]

Я знаю, что многие из нас поддерживают нашу собственную небольшую личную библиотеку с помощью инструментов и утилит, которые мы часто используем.

У меня было мое, так как мне было 16 лет, поэтому он вырос до довольно значительных размеров. С тех пор некоторые материалы, которые я написал, были добавлены в структуру. Я написал собственную небольшую реализацию деревьев выражений для использования с генетическими алгоритмами задолго до LINQ, что мне очень нравилось и гордилось в то время, конечно, сейчас оно довольно бесполезно. Но недавно я прошел через него и обновился до .NET 4.0 и повторно зажег интерес.

Так что мне любопытно, для чего вы используете свою библиотеку. Возможно, мы могли бы получить некоторые интересные идеи для полезных небольших фрагментов и поделиться ими между собой.

Итак, мои вопросы:

  • У вас есть небольшая библиотека утилиты?
  • Какую часть вы больше всего гордитесь и почему?

Приведите пример кода, если вам нравится :-)

31 голос | спросил Nobody 7 TueEurope/Moscow2010-12-07T18:30:15+03:00Europe/Moscow12bEurope/MoscowTue, 07 Dec 2010 18:30:15 +0300 2010, 18:30:15

16 ответов


26

Нет.

Я видел некоторые кошмарные эффекты от десятков разработчиков, добавляющих свои собственные маленькие библиотеки стиля «util.h» в проекты, и превратить их в гигантский беспорядок непоследовательных имен функций и поведения. Очень похоже на PHP. Поэтому по этой причине я избегаю этого.

Мне не нужно это делать, используя среды программирования, которые дают мне почти все инструменты и библиотеки, которые мне нужны, когда это возможно, например, C # и python.

ответил whatsisname 7 TueEurope/Moscow2010-12-07T22:29:51+03:00Europe/Moscow12bEurope/MoscowTue, 07 Dec 2010 22:29:51 +0300 2010, 22:29:51
16

SmartFormat

Моя любимая утилита - это то, что я написал - простой строковый построитель /форматировщик, который позволяет легко превращать данные в строки с правильной грамматикой.

Например, большинство программистов строят текст из шаблона: "There are {0} items remaining" но это приводит к грамматическим ошибкам: "There are 1 items remaining".

Итак, SmartFormat позволяет писать: "There {0:is|are} {0} item{0:|s} remaining".

Вы просто замените String.Format(...) на Smart.Format(...) и все!

Код SmartFormat является открытым исходным кодом: http://github.com/scottrippey/SmartFormat/wiki

ответил Scott Rippey 8 WedEurope/Moscow2010-12-08T02:21:44+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 02:21:44 +0300 2010, 02:21:44
7

K Комбинатор (C #, Scala)

Я часто использую комбинатор K в Ruby, в основном в сгибе, когда операция свертки выполняется с помощью побочного эффекта, а не возвращаемого значения, как в этом примере:

some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1 }

Это подсчитывает, как часто каждый элемент встречается в some_collection. К сожалению, он фактически не работает, поскольку блок должен возвращать новое значение аккумулятора на каждой итерации, но в назначениях Ruby оценивается назначенное значение.

Итак, вы должны экстренно возвращать новое значение аккумулятора следующим образом:

some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1; acc }

Но я нахожу такое явное упорядочение уродливым в этом функционально-иш-стиле, используя складки. Комбинатор K (называемый Object#tap в Ruby) для спасения:

some_collection.reduce(Hash.new(0)) {|acc, el| acc.tap { acc[el] += 1 }}

Я уже пропустил это пару раз в C # (в основном потому, что по какой-то причине мутаторы коллекции, такие как List.Add return void вместо this) и Scala, поэтому я переношу вокруг этого:

namespace GenericExtensions
{
    public static class GenericExtensions
    {
        public static T Tap<T>(this T o, Action<T> f)
        {
            Contract.Requires(o != null);
            Contract.Requires(f != null);

            f(o);
            return o;
        }

        public static T Tap<T>(this T o, Action f)
        {
            Contract.Requires(o != null);
            Contract.Requires(f != null);

            f();
            return o;
        }
    }
}

и в Scala:

class Tap[T](o: T) {
  def tap(f: T => Unit) = { f(o); o }
  def tap(f: => Unit) = { f; o }
}

object Implicits { implicit def any2Tap[T](o: T) = new Tap(o) }

Функция идентификации (Ruby)

Что-то, что мне не хватает в Ruby, - это красиво названный способ доступа к функции идентификации. Haskell предоставляет функцию идентификации под именем id, Scala под названием identity. Это позволяет писать код типа:

someCollection.groupBy(identity)

Эквивалент в Ruby равен

some_collection.group_by {|x| x }

Не совсем скатывается язык, не так ли?

Исправление

IDENTITY = -> x { x }

some_collection.group_by(&IDENTITY)

ForEach (.NET)

Еще один очень скудный метод в C #:

namespace IEnumerableExtensions
{
    public static class IEnumerableExtensions
    {
        public static void ForEach<T>(this IEnumerable<T> xs, Action<T> f)
        {
            Contract.Requires(xs != null);
            Contract.Requires(f != null);

           foreach (var x in xs) f(x);
        }
    }
}
ответил Jörg W Mittag 7 TueEurope/Moscow2010-12-07T21:10:40+03:00Europe/Moscow12bEurope/MoscowTue, 07 Dec 2010 21:10:40 +0300 2010, 21:10:40
6

У меня есть конвертер типов Java. Он имеет публичную подпись

public static <T> T convert(Object sourceValue, Class<T> destinationType)

, и он делает все возможное, чтобы преобразовать исходное значение в тип назначения. Это позволяет вам динамически печатать на статически типизированном языке: -)

Это действительно полезно с коробочными числовыми типами. Как раздражает то, что вы не можете поставить Integer туда, где Long ожидается? Нет проблем, просто преобразуйте его. Или что, если ваша функция ожидает double, но у вас есть null, чтобы положить туда? Kaboom, NPE. Но введите convert, и вы получите NaN

ответил Joonas Pulakka 8 WedEurope/Moscow2010-12-08T10:02:23+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 10:02:23 +0300 2010, 10:02:23
6

Из моего кода, который я написал, большая часть хорошего материала находится в CCAN сейчас, в то время как Я предпочитаю найти лучшие версии существующих проектов с открытым исходным кодом. В настоящее время я нахожу, что в настоящее время я пишу менее универсальный «разный» код, в пользу написания конкретных для приложения вариантов такого кода или написания модулей общего назначения, которые я могу сам выпускать.

С

Вот функция и typedef, которые я использовал несколько раз. Для приложений, которым требуется синхронизация, сложно просто выполнить миллисекунды:

#include <stdint.h>
#include <sys/time.h>

typedef int64_t msec_t;

static msec_t time_ms(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (msec_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

И более разнообразные функции C, которые я обычно использую снова и снова (и более):

/* Remove a trailing newline, if present. */
void chomp(char *buffer)
{
    if (!*buffer)
        return;

    while (*buffer)
        buffer++;

    if (buffer[-1] == '\n')
        buffer[-1] = 0;
}

/*
 * Skip whitespace, update the pointer, and return it.
 * Example:
 *
 * switch (*skipSpace(&s)) {
 *     case '\0':
 *         ...
 *     case '(':
 *         ...
 */
const char *skipSpace(const char **sptr)
{
    const char *s = *sptr;
    while (isspace(*s))
        s++;
    *sptr = s;
    return s;
}

/* Scramble an array of items uniformly. */
void scramble(void *base, size_t nmemb, size_t size)
{
    char *i = base;
    char *o;
    size_t sd;
    for (;nmemb>1;nmemb--) {
        o = i + size*(rand()%nmemb);
        for (sd=size;sd--;) {
            char tmp = *o;
            *o++ = *i;
            *i++ = tmp;
        }
    }
}

Haskell

Функция nub :: (Eq a) => [a] -> [a] - это O (n²), потому что по ее сигнатуре типа разрешено тестировать только два элемента. Простая альтернатива O (n log n) - это map head . group . sort, но для форматирования требуется принудительно весь список ввода, тогда как nub может сразу начать выпуск продукции. Ниже приведена альтернатива O (n log n) для nub, которая собирает уже увиденные элементы в Data.Set:

module Nub (nub') where

import Prelude
import Data.Set (empty, member, insert)

nub' :: Ord a => [a] -> [a]
nub' xs = loop xs empty where
    loop [] _ = []
    loop (x:xs) set =
        if x `member` set
            then loop xs set
            else x : loop xs (insert x set)

В Haskell я использую альтернативы sequence, mapM, forM, replicateM, и filterM. Эти действия генерируют список, но список не может использоваться до тех пор, пока действие не завершится полностью (если вы используете строгую монаду, такую ​​как IO). Альтернативы строят список в обратном порядке, а не образуют башню торсов, которую я обнаружил благодаря бенчмаркингу быстрее, по крайней мере, с GHC.

sequence' :: Monad m => [m a] -> m [a]
sequence' ms = loop ms [] >>= return . reverse where
    loop []     xs = return xs
    loop (m:ms) xs = do
        x <- m
        loop ms (x:xs)

mapM' :: Monad m => (a -> m b) -> [a] -> m [b]
mapM' f xs = sequence' $ map f xs

forM' :: Monad m => [a] -> (a -> m b) -> m [b]
forM' = flip mapM'

replicateM' :: Monad m => Int -> m a -> m [a]
replicateM' n x = sequence' (replicate n x)

filterM' :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM' pred xs = loop xs [] >>= return . reverse where
    loop []     xs' = return xs'
    loop (x:xs) xs' = do
        keep <- pred x
        loop xs (if keep then (x:xs') else xs')

Примечание: sequence_, mapM_ , forM_ и replicateM_ лучший выбор, если вы не заинтересованы в списке результатов.

ответил Joey Adams 7 TueEurope/Moscow2010-12-07T22:51:46+03:00Europe/Moscow12bEurope/MoscowTue, 07 Dec 2010 22:51:46 +0300 2010, 22:51:46
4

Я завершаю реализацию split /join ala Perl на языках, которые его не имеют.

Я также повторно реализовал atoi и itoa в C еще раз, чем хочу думать (вложенные нежелательные системы).

ответил Paul Nathan 8 WedEurope/Moscow2010-12-08T04:14:18+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 04:14:18 +0300 2010, 04:14:18
4

Нет.

Я делаю большую часть своей кодировки на Java, и лучше всего использовать повторную утилиту из «Apache Commons» и аналогичных проектов.

Если вы объективны в этом, мало случаев, когда ваша собственная коллекция «utils» станет значительным улучшением в отношении того, что уже сделали другие люди. И если это не улучшение, то ваша библиотека utils, вероятно, является пустой тратой времени разработки и неприятностью /нагрузкой для будущих сопровождающих.

ответил Stephen C 8 WedEurope/Moscow2010-12-08T09:01:42+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 09:01:42 +0300 2010, 09:01:42
3

У меня были некоторые манипуляции с датами, которые я выполнял с помощью Java, тогда я начал использовать JodaTime как Я слышал хорошие вещи об этом и его включение в Java 7 (не уверен, что это все еще так, но даже если его не все равно стоит использовать его imho).

Он превратил 50+ линейный класс в одну строку с тремя целыми вызовами метода.

Для любопытных это связано с получением даты для каждого дня n недель: например, показатель продаж в понедельник 10 недель назад и т. д. и т. д.).

И вот часть его

public static DateTime getDayPreviousWeek(DateTime dt, DayOfWeek dayOfWeek, int n_weeks) {
       return dt.minusWeeks(n_weeks).dayOfWeek().setCopy(dayOfWeek.getDayAsString());
}
ответил NimChimpsky 7 TueEurope/Moscow2010-12-07T19:13:57+03:00Europe/Moscow12bEurope/MoscowTue, 07 Dec 2010 19:13:57 +0300 2010, 19:13:57
2

У меня всегда есть пакет utils, даже в Java, но моя сборка PHP utils наиболее часто используется. В Java так много хороших библиотек, что у меня либо уже есть библиотека, включенная в проект, либо мне просто нужно создать несколько недостающих утилов самостоятельно. Библиотеки PHP имеют тенденцию делать слишком много для меня, чтобы они хотели включить их в мои проекты.

Я вроде как эта функция для PHP, с уточнением с помощью StackOverflow ...

function getValueFromDotKey(&$context, $name) {
    $pieces = explode('.', $name);
    foreach ($pieces as $piece) {
        if (!is_array($context) || !array_key_exists($piece, $context)) {
            // error occurred
            return null;
        }
        $context = &$context[$piece];
    }
    return $context;
}

Он похож на BeanUtils от Apache для Java, и я использую его для аналогичной цели, предоставляя элементам формы на языке шаблона один ключ, который может получить /установить вложенное значение в исходном массиве:

$source = array('a' => array('b' => 5));

$val = getValueFromDotKey($source, 'a.b');

Конечно, будучи PHP, я хотел, чтобы этот метод был как можно более легким, поэтому он не является довольно настолько функциональным, как BeanUtils ;)

ответил Nicole 7 TueEurope/Moscow2010-12-07T21:22:01+03:00Europe/Moscow12bEurope/MoscowTue, 07 Dec 2010 21:22:01 +0300 2010, 21:22:01
2

В стандартной библиотеке Scala отсутствуют некоторые наиболее часто используемые функции более высокого порядка.

Две такие функции, которые мне нужны чаще всего:

// #1: unfold
def unfold[T, R](init: T)(f: T => Option[(R, T)]): List[R] = f(init) match {
  case None => Nil
  case Some(r, v) => r :: unfold(v)(f)
}

// #2: zipWith
def zipWith[A, B, C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = {
  (xs, ys).zipped.map(f)
}
ответил missingfaktor 8 WedEurope/Moscow2010-12-08T08:33:28+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 08:33:28 +0300 2010, 08:33:28
1

В настоящее время нет. У меня был один, когда я делал C, но теперь, когда я занимаюсь Java, это уже не имеет смысла, учитывая все доступные стандартные библиотеки, плюс все плюсы, исходящие из проекта Apache.

Одной из полезных вещей в моей C lib была реализация быстрой и конечной конечной машины, которая позволяла определять конечный конечный автомат только с двумя строками и массивом строк. Его можно использовать для проверки строк против правил (например, «должно быть длиной 4..6 символов, сначала буквы, цифры отдыха»), но доступность регулярных выражений сделала эту вещь совершенно бессмысленной.

ответил user281377 8 WedEurope/Moscow2010-12-08T00:59:48+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 00:59:48 +0300 2010, 00:59:48
1

Теперь я не могу писать пользовательские интерфейсы рабочего стола без динамических диалогов на основе

ответил Mike Dunlavey 8 WedEurope/Moscow2010-12-08T01:43:05+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 01:43:05 +0300 2010, 01:43:05
1

Мне показалось, что я пишу много одного и того же кода в django, делаю эту общую вещь, затем эту общую вещь и, наконец, эту общую вещь. В основном получить один или несколько элементов из базы данных или сохранить результаты формы.

Если каждая из этих вещей происходит только один раз в представлении, то я могу использовать общие представления django. К сожалению, на самом деле это не очень сложно, и мне нужно было сделать несколько вещей в последовательности.

Итак, я пошел и написал еще более общую библиотеку представлений, которая работала, сначала создавая список действий из релевантных наборов запросов (или что-то еще), а затем завернула список в представление.

Мне все же приходится писать некоторые взгляды вручную, но они обычно достаточно сложны, что в них мало что можно использовать повторно. Вся плитка просто приземляется в другом месте, либо общий вид, либо как декоратор (как правило, украшенный общий вид). Обычно это составляет около 10% обработчиков, которые я пишу, поскольку какой-то общий обработчик может делать все остальное.

ответил SingleNegationElimination 8 WedEurope/Moscow2010-12-08T10:19:25+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 10:19:25 +0300 2010, 10:19:25
1

Да, но только для доменных структур идиом (например, контейнеров, специфичных для игровых объектов).

Как простые утилиты, чем что-либо сложное, я ничем не горжусь. В любом случае, я единственный пользователь, поэтому вам нечем гордиться.

ответил Klaim 8 WedEurope/Moscow2010-12-08T11:58:04+03:00Europe/Moscow12bEurope/MoscowWed, 08 Dec 2010 11:58:04 +0300 2010, 11:58:04
1

Косвенная сортировка C ++ на основе STL sort и шаблон-функтор.

Необходимость косвенной сортировки (в которой желаемым результатом были индексы перестановки , которые возникли бы при сортировке данных, но не в отсортированных данных ), появлялись много раз в ряде проектов. Я всегда задавался вопросом, почему STL не предоставила ему реализацию.

Другим был циклический вектор C ++, где положительные и отрицательные индексы по модулю с размером вектора (так что любые целые значения являются действительными индексами для вектора).

ответил rwong 9 ThuEurope/Moscow2010-12-09T10:58:17+03:00Europe/Moscow12bEurope/MoscowThu, 09 Dec 2010 10:58:17 +0300 2010, 10:58:17
-4

Я написал небольшой пакет utils, когда занимался разработкой Java в своем Comp. Sci класс в средней школе. Я больше всего горжусь своим генератором случайных чисел.

/**
* Returns a random integer.
*
* @returns    int    Random integer
*/
public static int getRandom()
{
    return 4; // Chosen by a fair dice roll.
              // Guaranteed to be random.
}

Поддержки к моему вдохновению.

ответил Josh K 7 TueEurope/Moscow2010-12-07T19:30:22+03:00Europe/Moscow12bEurope/MoscowTue, 07 Dec 2010 19:30:22 +0300 2010, 19:30:22

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132