Zeigen Sie eine xkcd an

36

xkcd ist das beliebteste Webcom von allen, und Sie werden ein Programm schreiben, das uns allen ein bisschen mehr Humor bringt.
Ihr Ziel bei dieser Herausforderung ist es, ein Programm zu schreiben, das eine Zahl als Eingabe verwendet und das xkcd und seinen Titeltext (Mauszeigentext) anzeigt.

Eingang

Ihr Programm nimmt eine positive Ganzzahl als Eingabe (nicht unbedingt eine, für die ein gültiger Comic existiert) und zeigt diese xkcd an. Bei einer Eingabe von 1500 sollte beispielsweise die Comic-Datei "Upside-Down Map" unter xkcd.com/1500 angezeigt werden. und dann entweder den Titel-Text auf der Konsole ausdrucken oder zusammen mit dem Bild anzeigen.

Aufgrund ihrer Nähe über den Kanal gibt es seit langem Spannungen zwischen Nordkorea und dem Vereinigten Königreich Großbritannien und Südirland. Due to their proximity across the channel, there's long been tension between North Korea and the United Kingdom of Great Britain and Southern Ireland.

Testfall 2 für n = 859:

Abgesehen vom Gehirn frage ich mich, wie viele schlecht geschriebene xkcd.com-Parsing-Skripte für diesen Titel (oder ;; "'{<< [' diesen Mouseover-Text) nicht funktionieren."

Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;"''{<<[' this mouseover text."

Ihr Programm sollte auch in der Lage sein, ohne Eingaben zu funktionieren und die gleiche Aufgabe für das neueste xkcd auszuführen, das Sie auf xkcd.com finden. Es sollte immer das neueste Programm anzeigen, selbst wenn ein neues auftaucht.

Sie müssen das Bild nicht direkt von xkcd.com beziehen, sondern können eine andere Datenbank verwenden, solange diese aktuell ist und bereits vor dem Beginn dieser Herausforderung vorhanden war. URL-Shortner, dh URLs, die keinen anderen Zweck haben als die Weiterleitung an einen anderen Ort, sind nicht zulässig.

Sie können das Bild auf beliebige Weise anzeigen, auch in einem Browser. Möglicherweise zeigen Sie jedoch nicht direkt einen Teil einer anderen Seite in einem Iframe oder ähnlichem an. ERKLÄRUNG: Sie können keine bereits vorhandene Webseite öffnen. Wenn Sie den Browser verwenden möchten, müssen Sie eine neue Seite erstellen . Sie müssen auch tatsächlich ein Bild anzeigen - die Ausgabe einer Bilddatei ist nicht zulässig.

Sie können den Fall, dass es kein Bild für einen bestimmten Comic gibt (z. B. ist es interaktiv oder das Programm wurde mit einer höheren Anzahl als der Anzahl der veröffentlichten Comics übergeben), auf eine angemessene Weise behandeln, einschließlich des Auslösens einer Ausnahme oder Ausdrucken einer Zeichenfolge mit mindestens einem Zeichen, sofern dies dem Benutzer irgendwie anzeigt, dass für diese Eingabe kein Bild vorhanden ist.

Sie können nur ein Bild anzeigen und dessen Titel-Text ausgeben oder eine Fehlermeldung für einen ungültigen Comic ausgeben. Andere Ausgaben sind nicht erlaubt.

Dies ist eine Herausforderung, so dass die wenigsten Bytes gewinnen.

Pavel
quelle
1
@LukeFarritor Sie können nur das Bild anzeigen und den Titeltext oder eine Fehlermeldung für einen ungültigen Comic ausgeben.
Pavel
9
Wenn Ihre Stichprobengröße 1 ist, import antigravityin Python;)
Wayne Werner
15
Lustige Tatsache, dass n=404 xkcd.com/404 eine 404-Seite ist.
Magic Octopus Urn
11
xkcd is everyone's favorite webcomic [Zitieren benötigt ]
Sanchises
11
Testfall: 859
Betseg

Antworten:

13

Perl + Curl + Feh, 86 84 75 Bytes

`curl xkcd.com/$_/`=~/<img src="(.*)" title="(.*?)"/;$_=$2;`feh "http:$1"`

Benötigt den -pSchalter. Ich habe dies in der Byteanzahl berücksichtigt.

ein Spaghetto
quelle
@Matt Es hat bei allen Comics funktioniert, die ich ausprobiert habe. Es werden also nur Bilder mit Alt-Text abgeglichen.
ein Spaghetto
Möglicherweise benötigen Sie keine Anführungszeichen um das Attribut src.
Conor O'Brien
Ich glaube nicht, dass Sie das ?in der ersten Matchgruppe brauchen . Sie könnten -pund $_=$2anstelle von verwenden print$2, aber dann wird der Titeltext erst gedruckt, nachdem feh geschlossen wurde. Ich bin mir nicht sicher, ob das gültig ist.
m-chrzan
@ m-chrzan Ja, sieht so aus, als könnte ich den Quantifikator dort ablegen, danke. Ich dachte darüber nach -p, war mir aber nicht sicher, wie sich das OP dabei anfühlen würde.
ein Spaghetto
@ ConorO'Brien Leider beachtet Randall gute HTML-Codierungspraktiken ... und das Erfassen der Anführungszeichen zitiert die Argumente nicht, da Backticks in Perl funktionieren.
ein Spaghetto
9

PowerShell v3 + 110 99 107 103 Bytes

iwr($x=((iwr "xkcd.com/$args").images|?{$_.title})).src.Trim("/") -outf x.jpg;if($x){ii x.jpg;$x.title}

Vielen Dank an Timmy für die Unterstützung beim Speichern einiger Bytes mithilfe von Inline-Zuweisungen.

Wenn keine Argumente übergeben werden, $argsist der Wert null und es wird nur der aktuelle Comic abgerufen. Laden Sie das Bild herunter, indem Sie es mit dem Alternativtext abgleichen und in eine Datei im aktuellen Ausführungsverzeichnis des Skripts kopieren. Zeigen Sie es dann mit dem Standard-Viewer für JPGs an. Der Alternativtext wird dann der Konsole angezeigt. iwrist ein Alias ​​fürInvoke-WebRequest

Wenn die übergebene Nummer (oder eine ungültige Eingabe) nicht übereinstimmt, schlägt der Prozess mit mindestens einem 404-Fehler fehl.

iwr(                                  # Request the comic image from XKCD
  $x=((iwr "xkcd.com/$args").images|  # Primary search to locate either the current image
                                      # or one matching an argument passed
     ?{$_.title}))                    # Find the image with alt text
        .src.Trim("/")                # Using the images associated link and strip the leading slashes
  -outf x.jpg                         # Output the image to the directory local to where the script was run
if($x){                               # Test if the image acquisition was successful
    ii x.jpg                          # Open the picture in with the default jpg viewer
    $x.title                          # Display alt text to console
}                                     # I'm a closing bracket.
Matt
quelle
Habe
@ConnorLSW Netter Ansatz in Ihrer Antwort. Dinge zum Nachdenken für das nächste Mal.
Matt
8

AutoIt , 440 Bytes

Ja, es ist lang, aber es ist stabil.

#include<IE.au3>
#include<GDIPlus.au3>
Func _($0='')
_GDIPlus_Startup()
$1=_IECreate('xkcd.com/'&$0)
For $3 In $1.document.images
ExitLoop $3.title<>''
Next
$4=_GDIPlus_BitmapCreateFromMemory(InetRead($3.src),1)
$6=_GDIPlus_ImageGetDimension(_GDIPlus_BitmapCreateFromHBITMAP($4))
GUICreate(ToolTip($3.title),$6[0],$6[1])
GUICtrlSendMsg(GUICtrlCreatePic('',0,0,$6[0],$6[1]),370,0,$4)
_IEQuit($1)
GUISetState()
Do
Until GUIGetMsg()=-3
EndFunc

Zunächst wird RegEx nicht zum Durchsuchen der Site verwendet (da ich keine Zeit habe, dies auf allen Comics zu testen), sondern es wird die Internet Explorer-API verwendet, um die imgTags des DOM zu durchlaufen, bis ein Eintrag mit einem Titeltext gefunden wird.

Der Binärdatenstrom wird aus der Bild-URL gelesen und mit GDIPlus in eine Bitmap gerendert. Diese wird dann in einer ansprechenden grafischen Benutzeroberfläche in automatischer Größe mit einem aktuellen Tooltip angezeigt, damit sie sich fast genau wie die Website verhält.

Hier ist ein Testfall ( _(859)):

)

mınxomaτ
quelle
4
Es wäre besser, wenn Sie die Klammer wieder in das Bild einfügen würden.
Matt
Wow, habe gerade herausgefunden, dass ich AutoIt unter Wine auf Ubuntu ausführen kann. Jetzt muss ich nur noch den IE dort zum Laufen bringen. Bei zweiten Gedanken ... +1 für die Antwort
ElPedro
2
@ElPedro Wenn Sie eine moderne CPU haben, verwenden Sie anstelle von Wein qemu KVM und seamlessRDP (im Grunde eine DIY-Parallele für Linux). Dies integriert Windows-Apps nahtlos in den Linux-Desktop und bietet 100% Kompatibilität + GPU-Passthrough. Nur ein Hinweis.
Mittwoch,
Vielen Dank @ mınxomaτ. Ich kann das mal ausprobieren. Ich arbeite den ganzen Tag mit Windows, bevorzuge es also, Linux (verschiedene Versionen) ohne Arbeit zu verwenden, aber ich bin immer daran interessiert zu experimentieren :) Tipp dankbar erhalten.
ElPedro
7

Powershell, 93 Bytes

93-Byte-Version zur Verwendung des lokalen Bildbetrachters.

$n=(iwr xkcd.com/$args).images|?{$_.title};$n.title;iwr ("http:"+$n.src) -OutF x.jpg;ii x.*

Sparte 2 Bytes durch Entfernen unnötiger Anführungszeichen, dann eine weitere Menge durch Verwenden von ("http:"+$n.src)anstelle von "https://"+$n.src.trim("/")-, da der imgsrc //bereits darauf enthalten ist und xkcd kein https benötigt.

$n=(iwr xkcd.com/$args).images|?{$_.title};$n.title;saps ("http:"+$n.src)

$n=(iwr "xkcd.com/$args").images|?{$_.title};$n.title;saps ("https://"+$n.src.trim("/"))

Sehr ähnlich zu Matts Powershell-Antwort (sollte wahrscheinlich ein Kommentar sein, aber wenig Ansehen)

Stattdessen wird im Standardbrowser eine neue Registerkarte / ein neues Fenster geöffnet, in dem unter anderem einige Bytes gespart werden.

iwr ist ein Alias ​​für Invoke-WebRequest

sapsist ein Alias, für Start-Processden 'es' im Standardkontext geöffnet wird.

colsw
quelle
Umgehen Sie die Grenzen der Regeln zum Öffnen einer vorhandenen Webseite, denn dies startet den Browser direkt über die bereits vorhandene .jpg-Datei (oder was auch immer), ist aber eine gute Antwort.
AdmBorkBork
@TimmyD könnte dann hier falsch verstanden haben - ich nahm an, dass Sie die xkcd-Webseite selbst verwenden können - Sie können einfach sapszu iwr"-OutF x.jpg; ii x. *" Wechseln und es an das Ende anhängen, wenn Sie möchten, dass es im Standard-Local geöffnet wird Bildbetrachter.
Colsw
1
Das OP hat angegeben, dass Sie keine bereits vorhandene Webseite öffnen dürfen. Die 93-Byte-Version ist meiner Meinung nach in Ordnung
ein Spaghetto
Ich denke nicht, dass dies immer gleich funktionieren wird, wenn Sie eine Nummer eingeben, die funktioniert, und eine Nummer, die nicht funktioniert. Es wird das Bild geöffnet, das vom vorherigen Lauf vorhanden war.
Matt
Ich akzeptiere die 93-Byte-Version, aber Ihre kürzere Version verstößt gegen die Bedingungen des Puzzles.
Pavel
4

R, 358 328 310 298 Bytes

f=function(x){H="http:";p=paste0;library(XML);a=xpathSApply(htmlParse(p(H,'//xkcd.com/',x)),'//div/img',xmlAttrs)[[1]];download.file(p(H,a[1]),'a');I=`if`(grepl('png',a[1]),png::readPNG,jpeg::readJPEG)('a');d=dim(I)/100;quartz(,d[2],d[1]);par(mar=rep(0,4));frame();rasterImage(I,0,0,1,1);cat(a[2])}

Mit neuen Zeilen und Kommentaren:

f=function(x){
H="http:"
p=paste0
library(XML) #Needed for xpathSApply, htmlParse and xmlAttrs
# The following line find the first img element and extract its attributes
a=xpathSApply(htmlParse(p(H,'//xkcd.com/',x)),'//div/img',xmlAttrs)[[1]]
download.file(p(H,a[1]),'a') #Download to a file called 'a'
I=`if`(grepl('png',a[1]),png::readPNG,jpeg::readJPEG)('a') #Check if png or jpeg and load the file accordingly
d=dim(I)/100 #convert dimension from pixel to inches (100 ppi).
quartz(,d[2],d[1]) #open a window of the correct dimension
par(mar=rep(0,4)) #Get rid of margins
frame() #Create empty plot
rasterImage(I,0,0,1,1) #Add png/jpeg to the plot
cat(a[2]) #Print title text to stdout
}

Screenshots von Testfällen:

für x = 1500: für x = 1500 (png)

für x leer:
für x = ''

Fall, wenn das Bild ein JPEG ist:
für x = 10 (jpeg)

x = 859:
x = 859

Plannapus
quelle
Ich frage mich, ob es notwendig ist, das Bild in den richtigen Dimensionen anzuzeigen. Als ich mit dieser Herausforderung rumgespielt habe, habe ich es einfach gemacht plot.new();rasterImage(...).
Billywob
@ Billywob Nun, es wäre völlig verzerrt, da die Standardgröße für die Handlung 7x7 Zoll beträgt. Es ist wahr, dass das OP nicht ausdrücklich darum gebeten hat, dass das Bild nicht verzerrt wird, aber ich bevorzuge es auf diese Weise :) Ich überlege jedoch, das xaxsund loszuwerden, yaxsda das Ergebnis immer noch verhältnismäßig wäre.
Plannapus
3

PHP, 95 Bytes

<?php echo str_replace("title=\"","/>",file_get_contents("https://xkcd.com/".$_GET["id"])); ?>

Speichere als main.php, starte den Server

php -S localhost:8123

Öffnen Sie http: // localhost: 8123 / main.php? Id = 1500

Евгений Новиков
quelle
2

Python 2.7, 309 299 295 274 Bytes

Volles Programm. Auf jeden Fall besser zum Golfen geeignet, aber nachdem ich xkcd-Comics so lange gelesen hatte, konnte ich das nicht zulassen (wer weiß, ob dies in Zukunft hilfreich sein wird, um xkcd einfach zu durchsuchen).

Wenn keine Eingabe übergeben wird, wird der aktuelle Comic abgerufen. Wenn eine gültige Comic-Nummer als Eingabe übergeben wird, wird dieser Comic abgerufen. Wenn eine ungültige Eingabe (kein Zahlencomic im gültigen Bereich) übergeben wird, wird ein Fehler ausgegeben.

Vorschläge zur Reduzierung der Byteanzahl sind willkommen! Ich werde es noch einmal überprüfen (und eine Erklärung hinzufügen), wenn ich mehr Zeit habe.

-10 Bytes dank @Dopapp

-21 Bytes dank @Shebang

import urllib as u,re
from PIL import Image
h='http://';x='xkcd.com/'
o=u.URLopener()
t=u.urlopen(h+x+raw_input()).read()
c=sum([re.findall(r,t)for r in[h+'imgs.'+x+'c.*s/.*\.\w{1,3}','\.\w{1,3}" t.*e="(.*)" a']],[])
Image.open(o.retrieve(c[0],'1.png')[0]).show();print c[1]
Ioannes
quelle
1
Sie können try:...und except:...zu try:n=...und ändern und except:n=''sparen Sie insgesamt 10 Bytes
Daniel
1
Warum hast du überhaupt eine tryAussage? Die Programmspezifikation besagt, dass Sie immer eine positive Ganzzahl erhalten.
Kade
@Shebang es sollte auch den neuesten Comic zurückgeben, wenn es keine Eingabe gibt. Ich konnte diesen Fall nur mit Ausnahme von Eingabefehlern bearbeiten.
Ioannes
1
@Joannes Warum nicht benutzen raw_input()? Standardmäßig kann der Benutzer drücken [Enter]und nwird die leere Zeichenfolge trotzdem enthalten. Wenn Sie diesen try-except-Block entfernen und t=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()auf 274 Bytes reduzieren.
Kade
Dies funktioniert nicht mehr, da xkcd-Bild-URLs verwendet werden https. Es ist jedoch immer noch gültig, da es zum Zeitpunkt der Veröffentlichung funktioniert hat. Damit es jetzt funktioniert, ändern Sie Zeile 3 und beginnen Sie mit h='https://'+1 Byte.
Mego
2

PHP, 42 Bytes

<?=@file('http://xkcd.com/'.$_GET[i])[59];

Speichern Sie es in einer Datei und starten Sie es auf einem Webserver Ihrer Wahl

Jared Mellentine
quelle
1
Willkommen bei PPCG! Ich kenne PHP nicht, aber es scheint keinen Teil Ihres Codes zu geben, der den Titeltext des Bildes abruft?
Pavel
1

JavaScript + HTML, 124 + 18 = 142 Bytes

i=>fetch(`//crossorigin.me/http://xkcd.com/${i||""}/info.0.json`).then(r=>r.json()).then(d=>(A.innerHTML=d.alt,B.src=d.img))
<img id=B><p id=A>

Herkunftsübergreifende Lösung dank Kaiidos Antwort hier .

17 Bytes ( //crossorigin.me/) können gespeichert werden, wenn der für die Verbindung zu xkcd.com erforderliche Proxy abgezogen werden kann ( Meta-Post dazu ).

Testschnipsel

f=
i=>fetch(`//crossorigin.me/http://xkcd.com/${i||""}/info.0.json`).then(r=>r.json()).then(d=>(A.innerHTML=d.alt,B.src=d.img))
<style>img{width:50%}</style><input id=I> <button onclick="f(I.value)">Run</button><br>
<img id=B><p id=A>

Justin Mariner
quelle
1

Python 3 + Requests + PIL, 192 186 Bytes

from requests import*
import PIL.Image as f
from io import*
r=get("https://xkcd.com/%s/info.0.json"%input()).json()
f.open(BytesIO(get(r["img"],stream=1).content)).show()
print(r["alt"])

Öffnet einen Bildbetrachter (welcher Standard auf dem System ist, auf dem er ausgeführt wird), der den Comic enthält, und sendet den Titeltext an die Konsole.

Textlich
quelle
1

Wolfram-Sprache 45 Bytes (Mathematica)

Import["https://xkcd.com/"<>#,"Images"][[2]]&

Verwendung mit Nummer:

%@"1500"

Verwendung ohne Nummer:

%@""
Vitaliy Kaurov
quelle