Afficher un xkcd

36

xkcd est le webcomic préféré de tous, et vous allez écrire un programme qui apportera un peu plus d'humour à nous tous.
Votre objectif dans ce défi est d’écrire un programme qui prendra un numéro en entrée et affichera ce xkcd et son titre-texte (texte mousover).

Contribution

Votre programme prendra un entier positif en entrée (pas nécessairement un pour lequel il existe un comique valide) et affichera xkcd: par exemple, une entrée de 1500 doit afficher le dessin "Upside-Down Map" sur xkcd.com/1500, et ensuite, imprimez son titre sur la console ou affichez-le avec l'image.

En raison de leur proximité de l'autre côté du canal, la tension existe depuis longtemps entre la Corée du Nord et le Royaume-Uni de Grande-Bretagne et d'Irlande du Sud. 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.

Cas de test 2, pour n = 859:

Bravo de côté, je me demande combien de scripts d’analyse xkcd.com mal écrits vont s’écraser sur ce titre (ou ;; "'' {<< ['ce texte survolé par la souris."

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

Votre programme devrait également pouvoir fonctionner sans aucune entrée et effectuer la même tâche pour le dernier xkcd trouvé sur xkcd.com, et il devrait toujours afficher le plus récent, même lorsqu'un nouveau apparaît.

Vous n'avez pas besoin d'obtenir l'image directement de xkcd.com, vous pouvez utiliser une autre base de données tant qu'elle est à jour et qu'elle existait déjà avant que ce défi ne soit relevé. Les raccourcis d’URL, c’est-à-dire les URL n’ayant d’autre but que de rediriger vers un autre emplacement, ne sont pas autorisés.

Vous pouvez afficher l'image de la manière que vous avez choisie, y compris dans un navigateur. Cependant, vous ne pouvez pas afficher directement une partie d'une autre page dans une iframe ou similaire. CLARIFICATION: vous ne pouvez pas ouvrir une page Web préexistante. Si vous souhaitez utiliser le navigateur, vous devez créer une nouvelle page . Vous devez également afficher une image - la sortie d'un fichier image n'est pas autorisée.

Vous pouvez gérer le cas où il n'y a pas d'image pour une bande dessinée particulière (par exemple, si elle est interactive ou si le programme a reçu un nombre supérieur au nombre de bandes dessinées publiées) de toute manière raisonnable, y compris en lançant une exception. , ou en imprimant une chaîne d'au moins un caractère, tant que cela signifie d'une manière ou d'une autre à l'utilisateur qu'il n'y a pas d'image pour cette entrée.

Vous pouvez uniquement afficher une image et générer son titre-texte ou générer un message d'erreur pour une bande dessinée non valide. Les autres sorties ne sont pas autorisées.

C'est un défi de , donc le moins d'octets gagne.

Pavel
la source
1
@LukeFarritor Vous pouvez uniquement afficher l'image et générer le texte du titre ou générer un message d'erreur pour une bande dessinée non valide.
Pavel
9
Si votre échantillon est égal à 1, import antigravityen Python;)
Wayne Werner
15
Fait drôle n=404 xkcd.com/404 est une page 404.
Urne Magique Octopus
11
xkcd is everyone's favorite webcomic [Citation nécessaire ]
Sanchises
11
Cas de test: 859
mardi

Réponses:

13

Perl + curl + feh, 86 84 75 octets

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

Nécessite l' -pinterrupteur. Je l'ai expliqué dans le nombre d'octets.

un spaghetto
la source
@ Matt Cela a fonctionné sur toutes les bandes dessinées que j'ai essayées. Cela correspond uniquement aux images avec alt-text ainsi.
Un spaghetto
Vous n’avez peut-être pas besoin des guillemets autour de l’attribut src.
Conor O'Brien
Je ne pense pas que vous ayez besoin ?du premier groupe de match. Vous pouvez utiliser -pet $_=$2au lieu de print$2, mais le texte du titre n’est imprimé qu’après la fermeture de feh. Je ne sais pas si c'est valide.
m-chrzan
@ m-chrzan Ouais, on dirait que je peux y déposer le quantificateur réticent, merci. J'ai pensé à utiliser -pmais je ne savais pas comment le PO réagirait.
Un spaghetto
@ ConorO'Brien Malheureusement, Randall observe de bonnes pratiques de codage HTML ... et capturer les guillemets ne cite pas les arguments en raison du fonctionnement des backticks en Perl.
un spaghetto
9

PowerShell v3 + 110 99 107 103 octets

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

Merci à Timmy d’avoir aidé à économiser des octets en utilisant des assignations en ligne.

Si aucun argument n'est transmis, la valeur $argsest nulle et la bande dessinée actuelle sera simplement obtenue. Téléchargez l'image, en faisant correspondre celle avec alt text, dans un fichier du répertoire en cours d'exécution du script. Puis affichez-le avec le visualiseur par défaut de jpg. Le texte alternatif est ensuite affiché sur la console. iwrest un alias pourInvoke-WebRequest

Si le nombre transmis (ou toute entrée non valide à cet égard) ne correspond pas, le processus échoue avec au moins une erreur 404.

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.
Mat
la source
Je viens tout juste de recevoir mon privilège de commentaire sur ce sous-marin maintenant, consultez ma réponse très similaire
Colsw
@ConnorLSW Belle approche dans votre réponse. Choses à penser pour la prochaine fois.
Matt
8

AutoIt , 440 octets

Oui, c'est long, mais c'est stable.

#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

Tout d'abord, cela n'utilise pas RegEx pour gratter le site (car je n'ai pas le temps de le tester sur toutes les bandes dessinées), mais utilise plutôt l'API Internet Explorer pour parcourir les imgbalises du DOM jusqu'à ce qu'il en trouve une avec un titre.

Le flux binaire est lu à partir de l'URL de l'image et rendu sous forme de bitmap à l'aide de GDIPlus. Ceci est ensuite affiché dans une belle interface graphique au format automatique avec une info-bulle qui lui permet de se comporter presque comme le site Web.

Voici un cas de test ( _(859)):

)

mınxomaτ
la source
4
Ce serait mieux si vous rajoutiez le crochet dans l'image.
Matt
Wow, je viens de découvrir que je peux exécuter AutoIt sous Wine sur Ubuntu. Maintenant, tout ce que j'ai à faire, c'est de faire fonctionner IE sur ce site. À bien y penser ... +1 pour la réponse
ElPedro
2
@ElPedro Si vous avez un processeur moderne, utilisez qemu KVM et seamlessRDP (un bricolage parallèle pour Linux) au lieu de wine. Cela intègre de manière transparente les applications Windows dans le bureau Linux et offre une compatibilité 100% + passerelle GPU. Juste un pourboire.
Mınxomaτ
Merci @ mınxomaτ. Je peux tenter le coup. Je travaille avec Windows toute la journée, je préfère donc utiliser Linux (différentes versions) sans travail, mais je suis toujours intéressé par les expériences :) Astuce reçue avec gratitude.
ElPedro
7

Powershell, 93 octets

Version de 93 octets pour utiliser l'afficheur d'images local.

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

Sauvegardé 2 octets en supprimant les doubles guillemets inutiles, puis un autre lot en utilisant à la ("http:"+$n.src)place de "https://"+$n.src.trim("/")- puisque le fichier imgsrc est //déjà présent , et que xkcd ne nécessite pas https.

$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("/"))

extrêmement similaire à la réponse de Matts Powershell, (devrait être probablement un commentaire mais une faible réputation)

Au lieu de cela, cela ouvre un nouvel onglet / fenêtre dans le navigateur par défaut, entre autres, en enregistrant quelques octets.

iwr est un alias pour Invoke-WebRequest

sapsest un alias pour Start-Processlequel ouvre 'il' dans le contexte par défaut.

Colsw
la source
En contournant les règles relatives à l'ouverture d'une page Web existante, il s'agit simplement de lancer directement le navigateur au format .jpg (ou autre) préexistant, mais c'est une bonne réponse.
AdmBorkBork
@TimmyD peut - être mal compris ici , alors - je suppose que vous pouvez utiliser la page Web xkcd lui - même - vous pouvez simplement changer sapspour iwret append `-OutF x.jpg;. Ii x *` la fin si vous voulez ouvrir dans le local par défaut Visionneuse d'images.
Colsw
1
L'OP a spécifié que vous n'êtes pas autorisé à ouvrir une page Web préexistante. La version de 93 octets, je pense que c'est bien
un spaghetto
Je ne pense pas que cela fonctionnera toujours de la même manière si vous donnez un nombre qui fonctionne, puis un nombre qui ne fonctionne pas. Cela ouvrira l'image qui existait depuis la précédente.
Matt
J'accepte la version de 93 octets, mais votre version la plus courte viole les conditions du puzzle.
Pavel
4

R, 358 328 310 298 octets

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])}

Avec de nouvelles lignes et commentaires:

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
}

Captures d'écran des cas de test:

pour x = 1500: pour x = 1500 (png)

pour x vide:
pour x = ''

cas où l'image est un jpeg:
pour x = 10 (jpeg)

x = 859:
x = 859

planificateur
la source
Je me demande s'il est nécessaire d'afficher l'image aux bonnes dimensions. Quand je jouais avec ce défi, je l'ai simplement fait plot.new();rasterImage(...).
Billywob
@Billywob Eh bien, il serait complètement déformé car la taille par défaut du tracé est de 7 x 7 pouces. Il est vrai que le PO n'a pas explicitement demandé à ce que l'image ne soit pas déformée mais je la préfère ainsi :) J'envisage toutefois de me débarrasser de la xaxset yaxsle résultat serait toujours proportionné.
Plannapus
3

PHP, 95 octets

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

Enregistrer en tant que main.php, exécutez le serveur

php -S localhost:8123

Ouvrez http: // localhost: 8123 / main.php? Id = 1500

Вгений Новиков
la source
2

Python 2.7, 309 299 295 274 octets

Programme complet. Certainement plus golfable, mais après avoir lu si longtemps les bandes dessinées de xkcd, je ne pouvais pas laisser passer cela (qui sait si cela sera utile dans le futur pour naviguer facilement dans xkcd).

Si aucune entrée n'est transmise, obtient la bande dessinée actuelle. Si un numéro de bande dessinée valide est passé en entrée, il obtient cette bande dessinée. Si une entrée non valide (et non un chiffre comique dans la plage valide) est transmise, une erreur est générée.

Toutes les suggestions sur la façon de réduire le nombre d'octets sont les bienvenues! Revisiterai (et ajoutera une explication) quand j'aurai plus de temps.

-10 octets grâce à @Dopapp

-21 octets grâce à @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
la source
1
Vous pouvez changer try:...et except:...à try:n=...et except:n='', vous permettant d' économiser 10 octets au total
Daniel
1
Pourquoi avez-vous même une trydéclaration? La spécification du programme indique que vous obtiendrez toujours un entier positif.
Kade
@ Sheebang devrait également renvoyer la dernière bande dessinée lorsqu'il n'y a aucune entrée. Je n'ai pas été en mesure de gérer cette affaire sans l'exception de l'erreur de saisie.
Ioannes
1
@Joannes Pourquoi ne pas utiliser raw_input()? Par défaut, l'utilisateur peut appuyer sur [Enter]et ncontiendra la chaîne vide de toute façon. Si vous supprimez ce bloc try-except et que t=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()vous le réduisez à 274 octets.
Kade
Cela ne fonctionne plus, car les URL d'image xkcd utilisent https. Cependant, il est toujours valide, car cela fonctionnait au moment de la publication. Pour que cela fonctionne maintenant, changez la ligne 3 pour commencer avec h='https://'+1 octet.
Mego
2

PHP, 42 octets

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

Enregistrer dans un fichier et le lancer sur le serveur Web de votre choix

Jared Mellentine
la source
1
Bienvenue chez PPCG! Je ne connais pas PHP, mais il ne semble pas y avoir une partie de votre code qui récupère le texte du titre de l'image?
Pavel
1

JavaScript + HTML, 124 + 18 = 142 octets

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>

Solution d'origine croisée grâce à la réponse de Kaiido ici .

17 octets ( //crossorigin.me/) peuvent être sauvegardés si le proxy requis pour se connecter à xkcd.com peut être soustrait ( meta post à ce sujet ).

Test Snippet

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
la source
1

Python 3 + requêtes + PIL, 192 186 octets

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"])

Ouvre une visionneuse d'images (celle par défaut sur le système sur lequel il est exécuté) contenant la bande dessinée et poste le texte du titre sur la console.

LyricLy
la source
1

Wolfram Language 45 octets (Mathematica)

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

Utilisation avec nombre:

%@"1500"

Utilisation sans nombre:

%@""
Vitaliy Kaurov
la source