Answer to Vote Ratio

18

This question is inspired by the fact that I love seeing questions with equal vote and answer counts...


So here's a simple challenge for y'all:

Challenge:

Given a codegolf.stackexchange question id, output the ratio between the question's votes and number of answers (e.g. votes/answers).

Specifics:

  • You may access the internet, but you may only access stackexchange.com and its various sub-domains. You may not use URL shorteners.

  • You may take input and give output in any standard format.

  • You must output the ratio as a decimal number in base 10, with at least 4 {accurate} digits after the decimal (zeros may be truncated).

  • If the question is unanswered, your program may produce undefined behavior.

  • You should use the score of the question as the vote-count, see here.

This is , least bytes in each language wins for that language, least bytes overall wins overall.

Here is a sample program in Python 3 + requests:

import requests
import json

id = input("id> ")
url = "https://api.stackexchange.com/2.2/questions/" + id + "?site=codegolf"
content = requests.get(url).text
question = json.loads(content)["items"][0]

print(float(question["score"]) / question["answer_count"])

Socratic Phoenix

Posted 2017-09-18T15:09:17.403

Reputation: 1 629

Does the ratio need at least 4 decimal digits after the decinal point even if they are zero? E.g. 41/4= 10.25 or 10.2500 – pizzapants184 – 2017-09-18T15:19:13.567

@pizzapants184 10.25 is fine – Socratic Phoenix – 2017-09-18T15:21:40.573

What if the challenge is not answered? Then the ratio would be infinite? – Mr. Xcoder – 2017-09-18T15:37:00.750

Do you mean score or total votes on the question? – AdmBorkBork – 2017-09-18T15:37:33.153

@Mr.Xcoder in that case, undefined behavior is okay – Socratic Phoenix – 2017-09-18T15:37:57.403

@AdmBorkBork technically score (which is displayed as votes on the main page) – Socratic Phoenix – 2017-09-18T15:38:32.330

Answers

10

JavaScript (ES6), 103 102 bytes

Needs to be run from the root level of api.stackexchange.com. Returns a Promise object containing the result.

n=>fetch(`questions/${n}?site=codegolf`).then(r=>r.json()).then(({items:[j]})=>j.score/j.answer_count)

If requiring that it be run from a specific path is allowed then that becomes 92 90 bytes.

n=>fetch(n+`?site=codegolf`).then(r=>r.json()).then(({items:[j]})=>j.score/j.answer_count)

Try it

Full URL added to enable it to work here.

f=
n=>fetch(`//api.stackexchange.com/questions/${n}?site=codegolf`).then(r=>r.json()).then(({items:[j]})=>j.score/j.answer_count)
onchange=_=>f(+i.value).then(t=>o.innerText=t)
<input id=i type=number><pre id=o>

Shaggy

Posted 2017-09-18T15:09:17.403

Reputation: 24 623

7Replace i=>(j=i.items[0]) with ({items:[j]})=>j to save a byte. – kamoroso94 – 2017-09-18T20:14:07.710

Nice trick, thanks, @kamoroso94. I'll have to remember that one. – Shaggy – 2017-09-18T22:25:12.800

8

Stratos, 40 bytes

-4 bytes thanks to Shaggy

f"¹⁵s/%²"r"⁷s"@0
{s"answer_⁰"
⁰s"score"/

Try it!

Stratos specialises in questions.

Explanation:

The code decompresses to the following:

f"api.stackexchange.com/questions/%?site=codegolf"r"items"@0
{s"answer_count"
⁰s"score"/

Starting from the first line, Stratos evaluates the dyads from right to left.

f"api.stackexchange.com/questions/%?site=codegolf"r"items"@0 means "evaluate the dyad @ with the left-hand argument f"api.stackexchange.com/questions/%?site=codegolf"r"items" and the right-hand argument 0. @ gets the nth element of a JSON array.

To evaluate f"api.stackexchange.com/questions/%?site=codegolf"r"items", we will next evaluate the dyad r with the left-hand argument f"api.stackexchange.com/questions/%?site=codegolf" and the right-hand argument "items". r gets the JSON array with the specified name.

Next, we will need to evaluate f"api.stackexchange.com/questions/%?site=codegolf". First, % is replaced with the input. f means "get the contents of this URL".

Now, we can move on to the second line. The newline means "add what we evaluated to the implicit argument list"

Next, we evaluate s (get string in JSON object with a certain name) with { and "answer_count". { takes an element from the implicit argument stack, returns it, and adds it back to the stack.

Then, we add the output of that to the implicit argument stack.

To evaluate ⁰s"score"/, we are applying the dyad / (divide) to ⁰s"score" and an element from the implicit argument stack.

To evaluate ⁰s"score" we are getting the string "score" from the JSON object from the 0th element in the implict argument stack.

Now, the output of / is printed and the program terminates.

Okx

Posted 2017-09-18T15:09:17.403

Reputation: 15 025

Save 4 bytes by ditching the API version (2.2/). – Shaggy – 2017-09-18T17:14:12.500

1@Shaggy Didn't realise the API version wasn't required, thanks. Not crossing out 44 :P – Okx – 2017-09-18T17:18:05.973

5

R + jsonlite, 111 bytes

function(n,x=jsonlite::fromJSON(sprintf('http://api.stackexchange.com/questions/%s?site=codegolf',n))$i)x$s/x$a

R-fiddle link

jsonlite is a nice JSON <-> R conversion library which works quite well. I wasn't about to golf a JSON parser for R...

Giuseppe

Posted 2017-09-18T15:09:17.403

Reputation: 21 077

You can save a byte by using the http protocol. Also, I'm guessing 142729 shouldn't be hardcoded in there? – Shaggy – 2017-09-18T15:50:35.323

@Shaggy good call, thank you. I copied and pasted too fast. – Giuseppe – 2017-09-18T15:53:16.510

4

T-SQL, 64 54 bytes

It is rare that SQL can beat (most) other languages! Instead of the API URL I went directly to the Stack Exchange Data Explorer:

SELECT 1.0*Score/AnswerCount FROM Posts WHERE Id=##i##

The ##i## isn't standard SQL, that's Stack Exchange's format to prompt for input.

Note that the data explorer source is only updated nightly, so values aren't current.

Will throw a divide by zero error on questions with no answers.

Edit: Saved 10 bytes by multiplying by 1.0 instead of an explicit CONVERT to FLOAT.

BradC

Posted 2017-09-18T15:09:17.403

Reputation: 6 099

can beat others, but not all :) – Okx – 2017-09-18T19:58:18.833

Oh maaan, I had another solution but I was in school so I never ended up posting it... Is my answer too similar to yours? Should I delete mine? – totallyhuman – 2017-09-18T20:05:26.287

@icrieverytim Ha, yep looks like pretty much the same query, although I just edited mine to save 10 more bytes. – BradC – 2017-09-18T20:11:45.633

@BradC I edited my answer into a Mathematica answer lol. – totallyhuman – 2017-09-18T20:50:39.677

3

PowerShell, 130 bytes

($a=(ConvertFrom-Json(iwr("http://api.stackexchange.com/questions/"+$args+"?site=codegolf")).content).items).score/$a.answer_count

Performs an Invoke-WebRequest against the URL, gets the .content thereof, does a ConvertFrom-Json of that content, and gets the .items of that JSON object. Stores that into $a and pulls out the .score as the numerator. The denominator is the .answer_count. That value is left on the pipeline and output is implicit.

If the question is unanswered, this should toss a "Divide by zero" error.

AdmBorkBork

Posted 2017-09-18T15:09:17.403

Reputation: 41 581

3

Japt, 83 82 bytes

Wanted to give this a try to see how it would work out, seeing as Japt can't natively accomplish it. Essentially all this is doing is evaling a compressed version of my JS solution. As Japt is JS then we can require that this be run from the root level of api.stackexchange.com and also return a Promise object containing the result.

Ox`fet®("quÀËs/{U}?ÐÒ=¬¸golf").È(r=>r.js()).È(i=>(j=i.ems[0]).sÖ/j.s³r_Öt)
  • View it
  • Try it - the extra bytes in this version are accounted for by the inclusion of //api.stackexchange.com/ in the URL and of console.log so you can actually see it working

Shaggy

Posted 2017-09-18T15:09:17.403

Reputation: 24 623

1

o0 Why have you made the code a link? It even messes with the userscript's byte count display lol. https://i.imgur.com/SO2zgAy.png

– totallyhuman – 2017-09-18T20:54:07.597

2

Mathematica, 124 bytes

N@("score"/.(u="items"/.Import["http://api.stackexchange.com/questions/"<>#<>"?site=codegolf","JSON"]))/("answer_count"/.u)&

Mathematica has a data type called Rule and it confuses the heck out of me. :P

totallyhuman

Posted 2017-09-18T15:09:17.403

Reputation: 15 378

1

Python 3 + requests, 149 bytes

-1 byte thanks to Mr. Xcoder.

from requests import*
u=get('http://api.stackexchange.com/questions/%s?site=codegolf'%input()).json()['items'][0]
print(u['score']/u['answer_count'])

totallyhuman

Posted 2017-09-18T15:09:17.403

Reputation: 15 378

The link is to Python 2. Btw, it throws an error both in Python 2 and Python 3 (on TIO). – None – 2017-09-18T15:38:36.277

No internet access on TIO whoops. I just used TIO for the answer formatting lol. – totallyhuman – 2017-09-18T15:42:28.337

I think that (for now) http suffices. – Mr. Xcoder – 2017-09-18T15:49:00.550

125 bytes – LyricLy – 2017-09-19T09:27:34.590

0

PHP, 167 bytes

<?$f=json_decode(gzdecode(file_get_contents('https://api.stackexchange.com/2.2/questions/'.$argv[1].'?site=codegolf')))->items[0];echo $f->score/$f->answer_count;

Turbo-fast crack at this. Save as a file and execute in the terminal like so:

php -f file.php 143083

Might be a way to reduce this.

Orpheus

Posted 2017-09-18T15:09:17.403

Reputation: 101