Из эмпирического тестирования кажется, что max()
и min()
в списке вернут первое в списке, которое соответствует max()
/ min()
в случае связи:
>>> test = [(1, "a"), (1, "b"), (2, "c"), (2, "d")]
>>> max(test, key=lambda x: x[0])
(2, 'c')
>>> test = [(1, "a"), (1, "b"), (2, "d"), (2, "c")]
>>> max(test, key=lambda x: x[0])
(2, 'd')
>>> min(test, key=lambda x: x[0])
(1, 'a')
>>> test = [(1, "b"), (1, "a"), (2, "d"), (2, "c")]
>>> min(test, key=lambda x: x[0])
(1, 'b')
И Отличное слежение Джереми подтверждает, что это действительно так.
В C или C ++ вы можете получить массу удовольствия от макросов. Например,
#define FOO(a,b) (a+b)/(1-a)
, если FOO (bar ++, 4) будет передан, он увеличится в два раза.
C / C ++:
Алгоритм Fast Inverse Square Root использует преимущества представления с плавающей точкой IEEE (код скопирован из Википедии):
float InvSqrt(float x)
{
union {
float f;
int i;
} tmp;
tmp.f = x;
tmp.i = 0x5f3759df - (tmp.i >> 1);
float y = tmp.f;
return y * (1.5f - 0.5f * x * y * y);
}
В PHP:
echo 'foo' == 0; // echos '1'
echo 'foo' == true; // echos '1'
echo 0 == true; // echos '0'
$foo = 'foo';
echo $foo['bar'] // echos 'f'
PHP имеет некоторые из наиболее раздражающих типов принуждения ...
Командные клавиши BASIC. В основном большинство команд имели сокращенную форму, которая обычно была первой буквой + (сдвиг + 2-я буква). Но поскольку набор символов на C64 был по умолчанию в верхнем регистре, эти команды выглядели бы странными символами. Вот краткий пример Hello World:
Возможно, у кого-то есть лучший пример с большим количеством мяса, но для длинных программ это выглядело совершенно нелепо.
Вот список сокращений: http://www.c64-wiki.com/index.php/BASIC_keyword_abbreviation
В языке C массивы можно индексировать так:
a[10]
, что очень распространено.
Однако менее известная форма (которая действительно работает!):
10[a]
, что означает то же самое, что и выше.
.В Python:
>>> x=5
>>> 1<x<10
True
>>> 1<x<3
False
Не WTF, а полезная функция.
Algol pass by name (иллюстрируется синтаксисом на Си):
int a[3] = { 1, 2, 3 };
int i = 1;
void f(int j)
{
int k;
k = j; // k = 2
i = 0;
k = j; // k = 1 (!?!)
}
int main()
{
f(a[i]);
}
Давайте проголосуем за все языки (такие как PL/I), которые пытались обойтись без зарезервированных слов.
Где еще можно законно написать такие забавные выражения, как:
IF IF THEN THEN = ELSE ELSE ELSE = THEN
(IF
, THEN
, ELSE
- имена переменных)
или
IF IF THEN THEN ELSE ELSE
(IF
- переменная, THEN
и ELSE
- подпрограммы)
PHP обрабатывает числовые значения в строках. Смотрите этот предыдущий ответ на другой вопрос для более подробной информации, но вкратце:
"01a4" != "001a4"
Если у вас есть две строки, содержащие разное количество символов, их нельзя считать равными. Ведущие нули важны, потому что это строки, а не числа.
"01e4" == "001e4"
PHP не любит строки. Он ищет любое оправдание, которое может найти, чтобы трактовать ваши значения как числа. Слегка изменяйте шестнадцатеричные символы в этих строках и внезапно PHP решает, что это больше не строки, это числа в научной нотации (PHP не заботится о том, что вы использовали кавычки) и они эквивалентны, потому что ведущие нули игнорируются для чисел. Чтобы подкрепить это замечание, вы обнаружите, что PHP также оценивает "01e4" == "10000"
как истинные, потому что это числа с эквивалентными значениями. Это документированное поведение, это просто не очень разумно.
INTERCAL, пожалуй, лучший компендиум странных особенностей языка. Моим личным любимым является утверждение COMEFROM, которое (почти) противоположно GOTO.
COMEFROM приблизительно противоположно GOTO в том, что он может принять исполнение состояние с любой произвольной точки кода на заявление КОМЕФРОМа. Дело в том, что код, где происходит передача состояния обычно дается в качестве параметра к КОМЕФРОМ. Случится ли передача до или после инструктажа на указанный пункт передачи зависит от используемый язык. В зависимости от используемый язык, несколько КОМЕФРОМ ссылаясь на одну и ту же точку отправления может быть недействительным, не детерминированным, выполняться в некотором роде приоритет, или даже побудить параллельно или в противном случае параллельное выполнение, как видно в Threaded Intercal. Простой пример заявление "КОМЕФРОМ Х" - это ярлык. x (что не обязательно должно быть физически расположенный вблизи соответствующий COMEFROM), который действует как "Ловушка". При выполнении кода достигает ярлыка, контроль передается к заявлению, следующему после КОМЕФРОМ. Эффект от этого в первую очередь для отладки (и понимание управляющего потока программа) чрезвычайно сложная, так как рядом с этикеткой нет никаких признаков этот контроль таинственным образом перепрыгнет в ещё один момент программы.
"особенность" восьмеричного преобразования JavaScript:
parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10
Больше подробностей здесь.
.Много встроенных переменных Perl:
$#
- не комментарий!$0
, $$
, и $?
- так же как и одноименные переменные оболочки$ˋ
, $&
, и $'
- странные совпадающие переменные$"
и $,
- странные переменные для разделителей списка и выходного поля$!
- как errno
в виде числа, но strerror(errno)
в виде строки$_
- переменная стелс , всегда используемая и никогда не виденная$#_
- номер индекса последнего подпрограммного аргумента. ... может быть@_
- (не)имена текущей функции... maybe$@
- последнее исключение%::
- символьная таблица$:
, $^
, $~
, $-
, и $=
- что-то связанное с выходными форматами$.
и $%
- номер строки ввода, номер выходной страницы$/
и $\
- разделители входных и выходных записей$|
- регулятор выходной буферизации$[
- измените базу массива с 0-базировки на 1-базировку на 42-базировку: WHEEE!$}
- - как ни странно, вообще ничего! $<
, $>
, $(
, $)
- реальные и эффективные UID и GID@ISA
- имена прямых суперклассов текущего пакета$^T
- время запуска скрипта в секундах эпохи$^O
- текущее имя операционной системы$^V
- какая версия Perl этоТам, откуда они взялись, их намного больше. Читайте полный список здесь.
.Веселье с автоматическим боксом и целочисленным кэшем на Java:
Integer foo = 1000;
Integer bar = 1000;
foo <= bar; // true
foo >= bar; // true
foo == bar; // false
//However, if the values of foo and bar are between 127 and -128 (inclusive)
//the behaviour changes:
Integer foo = 42;
Integer bar = 42;
foo <= bar; // true
foo >= bar; // true
foo == bar; // true
Беглый взгляд на исходный код Java приведет к следующему:
/**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Integer(int)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
Примечание: IntegerCache.high
по умолчанию имеет значение 127
, если только оно не установлено свойством.
Что происходит с автобоксингом, так это то, что и foo и bar один и тот же целочисленный объект, полученный из кэша, если только он явно не создан: например, foo = new Integer(42)
, таким образом, при сравнении равенства ссылок, они будут истинны, а не ложны. Правильный способ сравнения значения Целого числа - использование .equals;
Триграфы на C и C++.
int main() {
printf("LOL??!");
}
Это напечатает LOL|
, потому что триграф ?!
преобразован в |
.
JavaScript Таблица правды:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
" \t\r\n" == 0 // true
Источник: Даг Крокфорд
В JavaScript:
'5' + 3 gives '53'
В то время как
'5' - 3 gives 2
Я бы сказал, что вся эта штука с белыми пробелами на Python - моя величайшая особенность WTF. Правда, через некоторое время к ней привыкаешь больше или меньше, и с ней легко справляются современные редакторы, но даже после большей части полномасштабной разработки питона за последний год я всё ещё убежден, что это была Плохая Идея. Я прочитал все обоснования, но, честно говоря, это мешает моей продуктивности. Немного, но все равно это заусенец под седлом.
edit: Судя по комментариям, некоторые люди, похоже, думают, что я не люблю отступать от своего кода. Это неправильная оценка. Я всегда делал отступы в своем коде, неважно, на каком языке я говорю и вынужден я это делать или нет. Что мне не нравится, так это то, что именно отступ определяет, в каком блоке находится строка кода. Для этого я предпочитаю явные разделители. Среди прочих причин, я нахожу, что явные разделители облегчают вырезание и вставку кода.
Например, если у меня есть блок с отступом в 4 пробела и вставить его в конец блока с отступом в 8 пробелов, мой редактор (все редакторы?) понятия не имеет, принадлежит ли вставленный код блоку с отступом в 8 пробелов или внешнему блоку. OTOH, если у меня есть явные разделители, то очевидно, какому блоку принадлежит код и как он должен быть (пере)смещен - это делается путем интеллектуального поиска разделителей блоков.
редактирование 2: некоторые люди, которые дают комментарии, кажется, думают, что это особенность, которую я ненавижу, или что я думаю, что делает питон плохим языком. Опять же, это не так. Хотя мне все это и не нравится, но это не главное. Речь идет о самом странном языке, и я думаю, что это странно, в силу того, что это что-то очень, очень немногие (но >0) языки используют.
.Я всегда удивлялся, почему самая простая программа была:
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
В то время как она могла быть:
print "Hello World!"
Может быть, это, прежде всего, чтобы напугать студентов компьютерных наук ...
.Удивительно, что никто не упомянул о конструкциях цикла Visual Basic's 7.
For i As Integer = 1 to 10 ... Next
While True ... End While
Do While True ... Loop
Do Until True ... Loop
Do ... Loop While True
Do ... Loop Until True
While True ... Wend
Потому что засовывать ! перед вашим условием слишком сложно! путь !
Много пробелов в названии C:
typedef int i;
void foo()
{
struct i {i i;} i;
i: i.i = 3;
printf( "%i\n", i.i);
}
или с символами:
typedef char c;
void foo()
{
struct c {c c;} c;
c: c.c = 'c';
printf( "%c\n", c.c);
}
В JavaScript следующая конструкция
return
{
id : 1234,
title : 'Tony the Pony'
};
возвращает , что является синтаксической ошибкой из-за скрытой неявной вставки точки с запятой на новой строке после неопределенное
возврата
. Хотя, как и следовало ожидать, работает:
return {
id : 1234,
title : 'Tony the Pony'
};
- еще хуже, работает и эта (по крайней мере, в Chrome):
return /*
*/{
id : 1234,
title : 'Tony the Pony'
};
Вот вариант того же самого вопроса, который не дает синтаксической ошибки, просто молчаливо проваливается:
return
2 + 2;
APL (кроме ВСЕХ), возможность писать любую программу всего в одной строке.
например Conway's Game of Life в одной строке в APL:
alt text http://catpad.net/michael/APLLife.gif
Если эта строка не WTF, то ничего!
А вот -видео
] На Яве: [
] [int[] numbers() {
return null;
}
]
[] Может быть написано как: [
] [int numbers() [] {
return null;
}
] В JavaScript:
2 == [2]
// Even stranger
2 == [[[2]]]
// And down-right nutty
var a = { "abc" : 1 };
a[[[["abc"]]]] === a["abc"]; // this is also true
К счастью, добрые люди из stackoverflow.com объяснили мне все это: Почему 2 == [2] в JavaScript?
В C можно чередовать do / while с оператором switch. Вот пример memcpy, использующего этот метод:
void duff_memcpy( char* to, char* from, size_t count ) {
size_t n = (count+7)/8;
switch( count%8 ) {
case 0: do{ *to++ = *from++;
case 7: *to++ = *from++;
case 6: *to++ = *from++;
case 5: *to++ = *from++;
case 4: *to++ = *from++;
case 3: *to++ = *from++;
case 2: *to++ = *from++;
case 1: *to++ = *from++;
}while(--n>0);
}
}
Для тех, кто не знает, bc
- это "язык вычислений произвольной точности", и я использую его довольно часто для быстрых вычислений, особенно когда речь идет о больших числах ($
- это prompt):
$ bc -lq
12^345
20774466823273785598434446955827049735727869127052322369317059031795\
19704325276892191015329301807037794598378537132233994613616420526484\
93077727371807711237016056649272805971389591721704273857856298577322\
13812114239610682963085721433938547031679267799296826048444696211521\
30457090778409728703018428147734622401526422774317612081074841839507\
864189781700150115308454681772032
bc
долгое время была стандартной Unix-командой.
Теперь для "функции WTF". Это из man bc
(выделено мной):
quit: Когда оператор quit считывается, процессор bc завершается, независимо от того, где находится заявление о выходе. Например, "if (0 == 1) quit" приведет к завершению работы bc.
stop: Оператор остановки (расширение) - это выполняемый оператор, который приводит к тому, что процессор bc завершает работу только после его выполнения. Например, "if (0 == 1) stop" не приведет к завершению работы bc, так как остановка не выполняется.
Цитата Нила Фрейзера (посмотрите в конце этой страницы),
try {
return true;
} finally {
return false;
}
(в Java, но поведение, очевидно, такое же в JavaScript и Python). Результат предоставляется читателю в качестве упражнения.
РЕДАКТИРОВАТЬ: Пока мы обсуждаем эту тему, учтите также следующее:
try {
throw new AssertionError();
} finally {
return false;
}
powerbasic (www.powerbasic.com) включает директиву компилятора:
# BLOAT {bloatsize}
это увеличивает размер скомпилированного исполняемого файла на
байт. это было внесено в компилятор на тот случай, если людям, создающим исполняемый файл, не понравится маленький размер сгенерированного исполняемого файла. это заставляет EXE выглядеть больше, чтобы конкурировать с раздутыми языками программирования:)
Странные вещи, для которых можно использовать C++ шаблоны, лучше всего демонстрирует "Многомерные аналоговые литералы" , которая использует шаблоны для вычисления площади "нарисованных" фигур. Следующий код действителен на языке С++ для прямоугольника 3х3
#include"analogliterals.hpp"
using namespace analog_literals::symbols;
unsigned int c = ( o-----o
| !
! !
! !
o-----o ).area;
Или, другой пример с 3D кубом:
assert( ( o-------------o
|L \
| L \
| L \
| o-------------o
| ! !
! ! !
o | !
L | !
L | !
L| !
o-------------o ).volume == ( o-------------o
| !
! !
! !
o-------------o ).area * int(I-------------I) );
Большим преимуществом Perl по сравнению с Python является то, что при анализе текста есть возможность использовать регулярные выражения непосредственно как часть синтаксиса языка. Например,
if ($line =~ m/^Regex/) {
... code goes here
}
Perl также присваивает группы захвата непосредственно $1, $2 и т.д., что делает работу с ними очень простой. В зависимости от формата и структуры файлов журнала, которые вы пытаетесь разобрать, это может оказаться весьма полезным (или, если его можно разобрать как файл фиксированной ширины или с помощью более простых методов, совсем не очень полезным).
Все это просто синтаксический сахар, действительно, и другие языки также позволяют использовать регулярные выражения и захватывать группы (действительно, в связанной статье показано, как это сделать в Python). Вы просто должны написать немного больше кода и передать вокруг объектов, чтобы сделать это.
-121--2344683-Вау, я не знаю, что сказать, пожалуйста, идите и прочитайте о и узнайте sql немного, без обид, но это один из худших SQL я когда-либо казался.
SQL - язык, основанный на множестве, курсоры, в общем, плохие, бывают ситуации, когда они полезны, но встречаются довольно редко. Ваше использование курсоров здесь совершенно неуместно.
Ваша логика во втором курсоре также ошибочна, так как она выберет любую запись, которая включает друга, а не только необходимую дружбу.
Если вы хотите исправить его, вы можете попробовать присвоить второму курсору другое имя, но желательно начать сначала.
Установите составной ПК или уникальное ограничение для users_friends, тогда вам не нужно беспокоиться о проверке отношений, затем попробуйте что-то подобное.
INSERT INTO users_friends
SELECT
@inUserId,
users.user_id
FROM
users
WHERE
email = @inFriendEmail
-121--3549686- Не знаю, можно ли считать это языковой особенностью, но, в C++ почти любая ошибка компилятора, связанная с шаблонами, ежедневно доставляет значительное количество WTF многим программистам C++ по всему миру:)