लॉग वाले स्व


16

समस्या"

एक फ़ंक्शन log(या अन्य 3 अक्षर नाम) को परिभाषित करें जो जब बुलाया जाएगा लॉग / प्रिंट / लिखेंगे (जो कि प्रश्न में भाषा के लिए डिफ़ॉल्ट है) दोनों निर्देश (स्रोत के रूप में) और पहला तर्क। दूसरे शब्दों में:

i=777
j=333
log(i) //outputs: "log(i) 777"
log(i+j+1) //outputs: "log(i+j+1) 1111"

सभी व्यावहारिक उद्देश्यों के लिए आउटपुट i: 777पर्याप्त होगा, लेकिन कुछ भाषाओं में इसके लिए बहुत विशिष्ट प्रतिबिंब पुस्तकालय हैं, और यह कोई चुनौती नहीं होगी, इसलिए पूरे निर्देश को आउटपुट किया जाना चाहिए।

प्रेरणा स्त्रोत

इसके लिए प्रेरणा मुझे और एक अन्य प्रोग्रामर ने चर्चा की कि यह कितना परेशान करता है कि अक्सर (बुरे डिबगर्स के साथ), आप चीजों को लिखते हैं console.log("i:", i), जैसे कि हमने एक (बहुत पागल) जावास्क्रिप्ट (केवल नोड) समाधान बनाया (यह i: 777पूरी लाइन के बजाय आउटपुट करता है) source) जो बहुत लंबा था और मुझे कोडगॉल्फिंग की याद दिलाता था और मुझे आश्चर्य होता था कि अन्य (विशेष रूप से कोड गोल्फिंग) भाषाएं कितनी बेहतर होंगी।

बोनस

-10% : कोई फ़ाइल पढ़ने (संकलक से परे)

पुनश्च। यह मेरा पहला 'प्रश्न' है, इसलिए जो भी गलतियाँ मैंने की हैं, उन्हें इंगित करने के लिए स्वतंत्र महसूस करें।


1
CodeGolf.SE में आपका स्वागत है! मुझे व्यक्तिगत रूप से लगता है कि आपका प्रश्न बहुत ही अच्छा है, लेकिन आमतौर पर लोगों के जवाबों पर काम शुरू करने से पहले अस्पष्टता आदि को हल करने के लिए सैंडबॉक्स के माध्यम से प्रश्न विचार को चलाना बेहतर होता है।
मार्टिन एंडर

Thx और उपयोगी @ सैंडबॉक्स, इसका उपयोग करने के बारे में समझाने के लिए अच्छा हो सकता है help/on-topic(यह उल्लेख किया गया है, लेकिन मैंने इसे उस तरीके से जांचने के लायक नहीं माना है)।
डेविड मुल्डर

@ WolleVanillebärLutz: निश्चित रूप से यह नहीं है, क्या आपने किसी को यह दावा करते हुए देखा कि यह सच है?
डेविड मूलर

इनाम TrungDQ के लिए है (मुझे लगता है कि उसका समाधान सिर्फ एक कोड परिप्रेक्ष्य (हमारे नोड केवल समाधान की तुलना में बेहतर) से आश्चर्यजनक है, लंबाई की परवाह किए बिना), 24 घंटे इंतजार करना होगा, हालांकि इससे पहले कि मैं इसे पुरस्कार दे सकूं।
डेविड मूलर

जवाबों:


14

C (40 -10% = 36) (38 -10% = 34.2)

ध्यान दें कि, C में, एक logफ़ंक्शन को केवल एक विशिष्ट प्रकार के लिए परिभाषित किया जा सकता है। इसलिए, यह log"फ़ंक्शन" केवल intतर्क लेता है।

#define log(x)printf("log("#x") %d",x)

एक अधिक सामान्य समाधान तर्क को मुद्रित करने के लिए निर्दिष्ट करता है, तर्क के अलावा:

#define lg2(f,x)printf("lg2("#x") "f,x)

जिसका उपयोग उदाहरण के लिए lg2("%s", "I'm a string");या किया जाएगा lg2("%f", 3.1415)


मुझे नहीं लगता कि चारों ओर अंतिम कोष्ठक xआवश्यक हैं।
user12205

@ace: मुझे लगा कि यदि उपयोगकर्ता को तर्क में कुछ अजीब अक्षर डालते हैं, तो उनकी आवश्यकता हो सकती है, लेकिन प्रतिबिंब पर मुझे लगता है कि आप सही हैं। मैं उन्हें निकाल दूंगा।
nnonneo

10

अजगर (65 -10% = 58.5)

यह मानता है कि आपका कोड एक फ़ाइल में है (यह इंटरएक्टिव इंटरप्रेटर में इनवॉइस करने पर विषम आउटपुट उत्पन्न करता है):

import traceback as t
def log(x):print t.extract_stack()[-2][3],x

इसका परीक्षण पायथन 2.7.6 पर किया गया है।

उदाहरण:

def foo():
    x = 1
    log(x)
    for i in xrange(10):
        log(x+i+1)
    return x

log(foo())

आउटपुट

log(x) 1
log(x+i+1) 2
log(x+i+1) 3
log(x+i+1) 4
log(x+i+1) 5
log(x+i+1) 6
log(x+i+1) 7
log(x+i+1) 8
log(x+i+1) 9
log(x+i+1) 10
log(x+i+1) 11
log(foo()) 1

1
अच्छा! कहने का मतलब है, यह एक पागल सामान है जो मुझे एक प्रोग्रामर (मूल कार्य पर नकारात्मक सूचकांक: ओ) के रूप में दिलचस्पी लेता है: पी कुछ डॉक्स को खोजने के लिए बंद करता है
डेविड मुल्डर

9

C ++ 121 71 67 -10% = 60.3

#include<iostream>
#define log(x)std::cout<<"log("#x") "<<(x)<<"\n"

इस तरह इस्तेमाल किया:

int main() {
    int i = 777;
    int j = 333;
    log(i);
    log(i+j+1);
}

आउटपुट:

log(i) 777
log(i+j+1) 1111

यदि आप इसे C ++ के बजाय C में लिखते हैं, तो आप 30 char निकाल सकते हैं और एक-लाइनर बना सकते हैं #define log(x)printf("log(%s) %d\n",#x,x), लेकिन यह केवल पूर्णांकों का काम करेगा।
user12205

@ace: तब यह केवल एक प्रकार के लिए काम करता है। (इसके अलावा, यह मेरे द्वारा प्रस्तावित समाधान है, नीचे देखें)
nnonneo

@nneonneo मुझे इससे नफरत है जब मैं एक टिप्पणी पोस्ट करने से पहले ताज़ा करना भूल गया।
user12205

5

Rebol3 - 31.5 (35 - 10%)

यहाँ @draegtun से एक सरल कार्यान्वयन को छोटा किया गया है जो संख्याओं के लिए अच्छा काम करता है:

log: func[p][print[{log[}p{]}do p]]

इसे आउटपुट देना:

>> log: func[p][print[{log[}p{]}do p]]
>> i: 777
>> j: 333
>> log [i]
log[ 777 ] 777
>> log[i + j + 1]
log[ i + j + 1 ] 1111

यह बहुत अधिक लचीला हो सकता है (गैर-संख्या प्रकार के रूप को प्रदर्शित करने के लिए) 42.3 चार्ट (47 - 10%) पर )

log: func[p][print[{log}mold p mold/only do p]]

उत्पादन:

>> log: func[p] [print[{log}mold p mold/only do p]]
>> log [join "4" 4]
log [join "4" 4] "44"  ;; shows a string
>> log [1 + 2]
log [1 + 2] 3 

4

जावास्क्रिप्ट (325)

मुझे लगता है कि यह वह logकार्य है जिसे आप देख रहे हैं:

function log(m){L=(new Error()).stack.match(/(at log \([\s\S]+?at .+?:)\d+:\d+/m)[0].split('\n')[1].match(/:\d+:\d+/)[0];N=L.split(':')[1];C=parseInt(L.split(':')[2]);R=new XMLHttpRequest();R.open('GET',location.href,0);R.onload=function(){console.log(R.response.split('\n')[N-1].substr(C-1).split(';')[0]+' = '+m)};R.send()}

प्रयोग

<script>
function log(m){L=(new Error()).stack.match(/(at log \([\s\S]+?at .+?:)\d+:\d+/m)[0].split('\n')[1].match(/:\d+:\d+/)[0];N=L.split(':')[1];C=parseInt(L.split(':')[2]);R=new XMLHttpRequest();R.open('GET',location.href,0);R.onload=function(){console.log(R.response.split('\n')[N-1].substr(C-1).split(';')[0]+' = '+m)};R.send()}

function doSomething() {
  var a = 123; log(a); var b = "Hello, I am TrungDQ!"; log(b);
}
doSomething();
var message = "...or just do it out here";
log(message + "!");
</script>

उत्पादन

log(a) = 123
log(b) = Hello, I am TrungDQ!
log(message + "!") = ...or just do it out here!

लंबा कोड

<script>
function log(msg) {
  // Get the line number and offset of the line where is function is called
  var lineInfo = (new Error()).stack.match(/(at log \([\s\S]+?at .+?:)\d+:\d+/m)[0].split('\n')[1].match(/:\d+:\d+/)[0];
  var lineNum = lineInfo.split(':')[1];
  var charOffset = parseInt(lineInfo.split(':')[2]);

  // Get the file source
  request = new XMLHttpRequest();
  request.open('GET', window.location.href, true);

  request.onload = function() {
    // Get file source code
    var response = request.responseText;
    // Get the `log` line
    var line = response.split('\n')[lineNum - 1];
    // Get the `log` statement
    var logStatement = line.substr(charOffset - 1).split(';')[0];
    // Print it
    console.log(logStatement + ' = ' + msg);
  };
  request.send();
}

function doSomething() {
  var a = 123; log(a); var b = "Hello, I am TrungDQ!"; log(b);
}
doSomething();
</script>

केवल तभी काम करता है जब स्क्रिप्ट को <script>टैग के अंदर डाला जाता है जिसे .htmlदस्तावेज़ में डाला जाता है क्योंकि यह location.hrefस्रोत कोड प्राप्त करने के लिए अनुरोध भेजता है । JSfiddle, F12 Dev Tool Console, एंबेडेड .jsफाइलें काम नहीं करेंगी, मैं इसे हर जगह उपलब्ध कराने की कोशिश कर रहा हूं ...

वैसे भी, यह सवाल दिलचस्प है।


मुझे संदेह है कि यह क्रॉस ब्राउज़र है।
फरीद नूरी नेस्तत

3

स्काला - (221 - 10%) = 198.9

य मैक्रों! यह वास्तव में सामान का प्रकार है जिसके लिए वे हैं।

import language.experimental.macros
def log(p:Any)=macro l
def l(c:reflect.macros.Context)(p:c.Expr[Any])={import c.universe._;reify{println("log("+(c.Expr[String](Literal(Constant(show(p.tree)))).splice)+") "+p.splice)}}

पठनीय संस्करण:

import language.experimental.macros
def log(p: Any) = macro l
def l(c: reflect.macros.Context)(p: c.Expr[Any]) = {
  import c.universe._
  val inputString = show(p.tree)
  val inputStringExpr = c.Expr[String](Literal(Constant(inputString)))
  reify {
    println("log(" + (inputStringExpr.splice) + ") " + p.splice)
  }
}

उदाहरण:

log(1)
val x = 3
log(x)
val y = 4
log(x+y)

आउटपुट:

log(1) 1
log(x) 3
log(x.+(y)) 7

चूंकि स्केल में एक विधि कॉल है, इसलिए यह उस क्रिया सिंटैक्स को वापस जोड़ता है, लेकिन यह बहुत करीब है! यह अन्य मामलों के एक जोड़े में थोड़ा और अधिक क्रिया है।


वाह, यह फ़ंक्शन के अलावा @ को देखने के लिए काफी दिलचस्प है। सीखने के लिए इतना अच्छा सामान: D
डेविड मूलर

2

बैश (21 - 10% = 18.9)

इस:

alias log=echo;set -v

फिर logआप जैसे उपयोग करेंगे, उपयोग करेंगे echo:

log $((1+1))

या

A=2
B=3
log $((A+B))

यह विधि वह सब करेगी जो आवश्यक है; एक बोनस के रूप में, कुछ अतिरिक्त जानकारी भी मुद्रित की जाएगी, लेकिन कोई स्पष्ट नियम इसे मना नहीं करता है।


2

दे घुमा के

तर्क BASH में "(...)" का उपयोग करते हुए पारित नहीं किए जाते हैं, इसलिए मैं उस शैली को 'लॉग ()' फिट करने देता हूं:

$ log(){ echo "$FUNCNAME $@: $(($@))"; }
$ i=333
$ j=777
$ log i
log i: 333
$ log i+j+1
log i+j+1: 1111

$((...))$[...]इसके बजाय हो सकता है लेकिन मैंने वर्णों की गिनती नहीं की है, इसलिए यह अब तक मायने नहीं रखता है।

2

Clojure

(defmacro log[x] `(let [x# ~x] (println "log("'~x")" x#)))

समरूपता के अपने फायदे हैं!

काम में लाना:

(def i 777)
(def j 333)
(log i) ;Prints log( i ) 777
(log (+ i j 1)) ;Prints log( (+ i j 1) ) 1111

आइए देखें कि क्या हो रहा है macroexpand:

(macroexpand '(log (+ i j 1))) 
;; Prints the following: 
(let* [x__1__auto__ (+ i j 1)] (clojure.core/println "log(" (quote (+ i j 1)) ")" x__1__auto__))

यदि आप उद्धृत xकरते हैं, तो क्या आपको वास्तव में एक मध्यवर्ती gensym (यानी। x#) का उपयोग करने की आवश्यकता है ? मुझे लगता है कि आप केवल एक बार अभिव्यक्ति का मूल्यांकन करेंगे (btw, मैं कोई क्लोजर विशेषज्ञ नहीं हूं)
coredump

2

जूलिया, 51 * 0.9 = 45.9

julia> x=4
4
julia> macro log(x) println("log($x) $(log(eval(x)))") end
julia> @log(x)
log(x) 1.3862943611198906

वैकल्पिक रूप से, लेकिन नियमों को पूरा नहीं करते

julia> @show log(x)
log(x) => 1.3862943611198906

2

Tcl, 42.3 (47 - 10%)

proc log c {puts [dict g [info fr -1] cmd]\ $c}

उपयोग:

set i 777
set j 333
log $i  ;#outputs: "log $i 777"
log [expr {$i+$j+1}] ;#outputs: "log [expr {$i+$j+1}] 1111"

संपादित करें : छोटा सुधार


0

आम लिस्प - 119.7 (133 -10%)

(defmacro @(&whole f &rest r)(let((g(gensym)))`(let((,g(multiple-value-list,@r)))(progn(format t"~s~{ ~a~}
"',f,g)(values-list,g)))))
  • नामित @क्योंकि logमानक लॉगरिदम फ़ंक्शन है और डिफ़ॉल्ट रूप से लॉक किया गया है (कम से कम SBCL पर)। इसके अलावा, @केवल एक चरित्र लंबा है।
  • एक के रूप में कार्य करता है progn, एक चर संख्या में तर्क ले रहा है, लेकिन मानक आउटपुट पर प्रिंट करता है। वास्तविक अनुप्रयोगों में, मैं शायद signalस्पेस-अलग-अलग आउटपुट को प्रिंट करने के बजाय एस-अभिव्यक्ति के साथ एक शर्त रखूंगा।
  • मौजूदा क्लोजर समाधान के विपरीत, हम अंततः लॉग इन अभिव्यक्ति के मूल्य को वापस कर देते हैं, ताकि (@ x)जब भी उपयोग किया जा सके x
  • मुद्रण का उपयोग करता है prin1, जो एक- readस्ट्रिंग स्ट्रिंग को आउटपुट करता है । लॉग अभिव्यक्तियों को पुन: पेश करने की कोशिश करते समय यह उपयोगी है।
  • सभी संभावित प्रकारों को संभालता है (देखें सी उत्तर)
  • उत्परिवर्ती मूल्यों को ध्यान में रखता है
  • विभिन्न आउटपुट उत्पन्न नहीं करता है (देखें स्काला उत्तर)
  • एक फ़ाइल से और REPL से काम करता है (पायथन जवाब देखें)
  • ब्राउज़र / दुभाषिया चाल (पायथन ट्रेसबैक, जावास्क्रिप्ट अनुरोध) की आवश्यकता नहीं है

नमूना आउटपुट:

CL-USER>(@ (+ 3 2))   ; user input
(@ (+ 3 2)) 5         ; printed output
5                     ; result of expression

CL-USER> (@ (values 3 4))  ; input
(@ (VALUES 3 4)) 3 4       ; logging
3                          ; first value
4                          ; second value

CL-USER>(@ (round 3.4))
(@ (ROUND 3.4)) 3 0.4000001
3                          ; rounded value
0.4000001                  ; delta

और अंत में, अगर मैं ऊपर लॉग इन करता हूं, तो defmacroमेरे पास अन-गोल्ड संस्करण है:

CL-USER> (@ (defmacro @(&whole f &rest r)(let((g(gensym)))`(let((,g(multiple-value-list,@r)))(progn(format t"~s~{ ~a~}
"',f,g)(values-list,g))))))
STYLE-WARNING: redefining COMMON-LISP-USER::@ in DEFMACRO
(@
 (DEFMACRO @ (&WHOLE F &REST R)
   (LET ((G (GENSYM)))
     `(LET ((,G (MULTIPLE-VALUE-LIST ,@R)))
        (PROGN
         (FORMAT T ,"~s~{ ~a~}
"
                 ',F ,G)
         (VALUES-LIST ,G)))))) @
@ ; actual result

0

PHP 138

आप logएक और मॉड्यूल ( APD) का उपयोग किए बिना PHP में पुनः लोड नहीं कर सकते logg, इसलिए मैंने इसके बजाय उपयोग किया, मैं logउदाहरण के साथ ज़रूरत पड़ने पर फिर से सबमिट कर सकता हूं । यह मामूली है, लेकिन अधिक पापी मुझे लगता है कि यह मान लेता है कि लॉग फ़ंक्शन अपने आप एक लाइन पर है। मैं अपने जवाब को टिप्पणियों के अनुसार तय कर सकता हूं।

<?php function logg($v){$b=debug_backtrace()[0];$h=fopen($b['file'],"r");for($i=0;$i<$b['line']&&$l=fgets($h);$i++);echo trim($l)." $v";}

उदाहरण आउटपुट:

for ($i=1; $i<10; $i++) {   
  $j=$i+1;
  $k=$j+1;
  logg($i+$j+$k);
  echo "\n";
}
/*
logg($i+$j+$k); 6
logg($i+$j+$k); 9
logg($i+$j+$k); 12
logg($i+$j+$k); 15
logg($i+$j+$k); 18
logg($i+$j+$k); 21
logg($i+$j+$k); 24
logg($i+$j+$k); 27
logg($i+$j+$k); 30
*/

-2

जावास्क्रिप्ट 55 53

function log(x){console.log('log("'+x+'") '+eval(x))}

उपयोग:

var i = 777,
    j = 333;
log("i")
log("j")
log("12*4")
log("i*j-4")

आउटपुट:

log("i") 777
log("j") 333
log("12*4") 48
log("i*j-4") 258737

आप दोहरे उद्धरण चिह्नों का उपयोग करें "अन्यथा यह काम नहीं करेगा।


इसके बावजूद कि मैंने पहले से दिए गए उदाहरण के छद्म कोड का पालन न करके नियमों को झुका दिया, इससे भी बड़ी समस्या यह है कि यह केवल तभी काम करता है जब और यदि वैश्विक संदर्भ में चर को परिभाषित किया जाता है (मुझे पता है कि मूल्यांकन मूल्यांकन संदर्भ इससे कहीं अधिक जटिल है, लेकिन बिंदु खड़ा है)
डेविड मूलर

चुनौती की बात यह थी कि आप एक स्ट्रिंग ... -1 उत्तीर्ण नहीं होते हैं
दरवाज़े

बिंदु यह नहीं कर log("i:", i)रहा था ... मुझे नहीं लगता कि यह बिना 'या "js के नहीं किया जा सकता ... आप इसका उपयोग करके इसे छोटा बना सकते हैं console.log('log('+o+')'+eval(x))लेकिन आउटपुट कोड लाइन (जो परवाह करता है) से मेल नहीं खाएगा
rafaelcastrocouto

2
आप इसे एक ही पंक्ति में कर सकते हैं, मैंने इसे नोड में किया है, कैसे? एक त्रुटि को फेंककर, स्टैक प्राप्त करना, फ़ाइल पढ़ना और लाइन निकालना। हां, थोड़े पागल: डी। इसके अतिरिक्त इसका उपयोग करना संभव हो सकता है arguments.callee.caller.toString(), लेकिन मैं यह पता लगाने में सक्षम नहीं था कि कौन सी लाइन है जब आपके पास दो लॉग हैं।
डेविड मुल्डर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.