[PYTHON] J'ai fait une simple minuterie qui peut être démarrée depuis le terminal

Cet article a été rédigé en tant qu'article du 9ème jour du Calendrier de l'Avent IS17er. Cliquez ici pour l'article sur Jour 8.

Aperçu

J'ai créé une application de minuterie qui peut être démarrée à partir du terminal à l'aide d'une bibliothèque appelée Tkinter of Python. Vous pouvez voir comment cela fonctionne en regardant l'image. Veuillez l'utiliser par tous les moyens! tmr.png

Oui, faisons une simple minuterie

Récemment, j'ai perdu ma concentration, et quand j'étais assis devant mon ordinateur, deux heures s'étaient écoulées avant de le savoir, j'ai donc créé une minuterie qui peut être facilement démarrée depuis le terminal afin que je puisse me concentrer pendant un court laps de temps et gérer le temps. J'ai décidé de le faire (hier soir).

Concept

(Quand j'écrivais cette section, je n'écrivais pas encore le programme) En tant qu'image de l'application à créer cette fois, par exemple $ tmr 5m30s -t kadai L'image est que si vous appuyez sur une commande comme celle-ci, une petite fenêtre apparaîtra dans le coin supérieur droit de l'écran et le compte à rebours. «-t» est éventuellement le titre de la minuterie. Même si j'implémente une fonction très compliquée, je ne vais pas l'utiliser, donc je me demande si tout va bien pour l'instant. Je me demande s'il existe un son de notification facultatif comme Slack. Après cela, si la couleur change de manière aléatoire à chaque fois que vous la démarrez, vous pouvez l'utiliser sans vous ennuyer.

Écrire

Je n'ai pas du tout écrit d'application de bureau parce que c'est généralement un système Web, mais quand je l'ai un peu cherché sur Google, Tkinter semble amusant, alors j'ai écrit ceci J'ai décidé de l'utiliser. Il semble que vous puissiez facilement créer une interface graphique avec Python en utilisant Tkinter.

code

Le code faisait environ 100 lignes, alors collez le tout. En raison de cette brièveté, j'en ai fait un fichier. N'hésitez pas à le personnaliser.

tmr.py


#!/usr/bin/env python
# -*- coding: utf8 -*-
import sys
import re
import argparse
import random
import Tkinter as tk

class App():
  def __init__(self):
    self.window_size = 150
    self.fps = 10
    self.font_size = 23
    self.option = self.parse_args()
    self.time = self.get_timesec()
    self.period = self.time
    self.root = self.set_root()
    self.canvas = self.set_canvas()
    self.label = self.set_label()
    self.progress = self.init_progress()
    self.update()
    self.run()

  def parse_args(self):
    parser = argparse.ArgumentParser(description="Show simple countdown timer on desktop.")
    parser.add_argument("period", action="store", type=str, help="Set period for your timer.")
    parser.add_argument("-t", dest="title", action="store", default="Timer", help="Set title for your timer.")
    parser.add_argument("-n", dest="notify", action="store_false", default=True, help="Disable notification.")
    return parser.parse_args()

  def get_timesec(self):
    if re.search("\A(?:\d+h)?(?:\d+m)?(?:\d+s)?$", self.option.period) is None:
      print "Incorrect format of period:", self.option.period
      print "Set period like 10m30s"
      sys.exit()
    time = 0
    if re.search("\d+h", self.option.period) is not None:
      time += int(re.search("\d+h", self.option.period).group(0)[:-1]) * 3600
    if re.search("\d+m", self.option.period) is not None:
      time += int(re.search("\d+m", self.option.period).group(0)[:-1]) * 60
    if re.search("\d+s", self.option.period) is not None:
      time += int(re.search("\d+s", self.option.period).group(0)[:-1])
    if time > 9 * 3600 + 59 * 60 + 59:
      print "Too long period."
      sys.exit()
    return time

  def set_root(self):
    root = tk.Tk()
    root.resizable(0,0)
    window_size = self.window_size
    colors = ["#f44336", "#E91E63", "#9C27B0", "#673AB7", "#3F51B5", "#2196F3", "#03A9F4", "#00BCD4", "#009688", "#4CAF50", "#8BC34A", "#CDDC39", "#FFEB3B", "#FFC107", "#FF9800", "#FF5722", "#795548", "#9E9E9E", "#607D8B"]
    root.title(self.option.title)
    root.geometry("%dx%d+%d+%d" % (window_size, window_size, root.winfo_screenwidth() - window_size, 0))
    root.configure(bg=random.choice(colors))
    root.attributes("-alpha", 0.5)
    root.attributes("-topmost", True)
    return root

  def set_label(self):
    window_size = self.window_size
    label = self.canvas.create_text((window_size / 2, window_size / 2), text="")
    self.canvas.itemconfig(label, font=("Menlo-Regular", self.font_size))
    return label

  def set_canvas(self):
    window_size = self.window_size
    canvas = tk.Canvas(self.root, width=window_size, height=window_size, highlightthickness=0)
    canvas.grid()
    return canvas

  def format_time(self, timesec):
    m, s = divmod(timesec, 60)
    h, m = divmod(m, 60)
    if h == 0:
      if m == 0:
        return "%02ds" % (s)
      else:
        return "%02dm%02ds" % (m, s)
    else:
      return "%dh%02dm%02ds" % (h, m, s)

  def init_progress(self):
    color = self.root["bg"]
    window_size = self.window_size
    progress = self.canvas.create_arc(window_size * 0.1, window_size * 0.1, window_size * 0.9, window_size * 0.9, style="arc", width="%d" % (window_size / 15), outline=color, start=90, extent=360)
    return progress

  def update(self):
    window_size = self.window_size
    self.canvas.itemconfig(self.label, text=self.format_time(self.time))
    extent = 360.0 * self.time / self.period
    self.canvas.itemconfig(self.progress, start=450-extent, extent=extent)
    self.time -= 1.0 / self.fps
    if self.time < 0:
      if self.option.notify:
        print '\a'
      sys.exit()
    self.root.after(1000 / self.fps, self.update)

  def run(self):
    self.root.mainloop()

app = App()

Comment utiliser

Je l'ai écrit dans GitHub, mais ici je n'ose pas le cloner.

  1. Copiez le code ci-dessus et enregistrez-le sous le nom de fichier tmr (sans extension).
  2. chmod 755 tmr
  3. Ajoutez quelque chose comme export PATH = $ PATH: / Users / [username] / timer à `~ / .bash_rc``` ou` ~ / .bash_profile```. Si vous ne comprenez pas cela, recherchez sur Google l'ajout de PATH.
  4. Redémarrez le terminal en faisant `source ~ / .bash_rc``` ou` source ~ / .bash_profile```
  5. Essayez de frapper tmr 10m30s```!

Difficultés (explication du code)

En fait, il y en a pas mal, mais pour le moment, il y en a.

Expressions régulières

C'est une expression régulière que tout le monde aime.

"\A(?:\d+h)?(?:\d+m)?(?:\d+s)?$"C'est le début"\A(?:\d+h)?(?:\d+m)?(?:\d+s)?\z"J'ai écrit cela et produit None pour toujours. Habituez-vous aux expressions régulières.



#### Comment écrire du code de manière concise
 Python a un grand nombre de fonctions utiles en standard, c'est donc une bonne idée de les vérifier d'abord même si vous voulez écrire quelque chose vous-même. Dans la plupart des cas, il est plus rapide de l'écrire par vous-même, mais comme c'est une mauvaise pratique que la gestion des boîtiers d'angle soit gênante et que la lisibilité se détériore, j'ai simplement cherché sur Google les fonctions existantes. De plus, dans le cas de Python, plusieurs fonctions existantes se comportent souvent de la même manière, il a donc fallu du temps pour sélectionner une bibliothèque afin que les fonctions existantes aient un bon sens de l'unité. Cela peut être une maladie professionnelle.

## à la fin
 Vous pouvez le cloner depuis [GitHub](https://github.com/xuzijian629/timer), veuillez donc l'utiliser (si vous avez des problèmes, vous pouvez copier le code tel quel). Je suis content de pleurer si vous jouez la vedette! De plus, les sons de notification, etc. ne sont pas implémentés au moment de la rédaction, je peux donc les ajouter plus tard.

 En passant, dans le cas de Mac, il existe une commande géniale appelée `` dire ''
```$ sleep 100 &&dire fin```
 Si vous faites quelque chose comme ça, il lira "Fin" après 100 secondes (si la langue est définie sur le japonais).

 Eh bien, à demain ~

 [Ajout] Le son de notification a été implémenté (le code ci-dessus a été corrigé).
```print '\a'```
 Tu peux y aller! N'est-ce pas un dieu Python ...!


Recommended Posts

J'ai fait une simple minuterie qui peut être démarrée depuis le terminal
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
J'ai fait un module qui peut être glitch facilement, mais je ne peux pas passer l'argument de entry_points
[Atcoder] [C ++] J'ai fait un outil d'automatisation de test qui peut être utilisé pendant le concours
J'ai fait une minuterie de cuisine à afficher sur la barre d'état!
J'ai créé une image Docker qui peut appeler FBX SDK Python à partir de Node.js
J'ai fait une minuterie pomodoro dure qui fonctionne avec CUI
J'ai étudié le prétraitement qui peut être fait avec PyCaret
J'ai créé un plug-in qui peut faire "Daruma-san tombé" avec Minecraft
Puis-je être un data scientist?
J'ai créé un outil pour générer automatiquement un simple diagramme ER à partir de l'instruction CREATE TABLE
J'ai fait un package qui peut comparer des analyseurs morphologiques avec Python
À partir d'un livre que le programmeur peut apprendre ... (Python): trouver la valeur la plus fréquente
J'ai fait un bot mou qui m'informe de la température
J'ai fait une commande pour afficher un calendrier coloré dans le terminal
J'ai fait un programme qui calcule automatiquement le zodiaque avec tkinter
[python] J'ai créé une classe qui peut écrire rapidement une arborescence de fichiers
J'ai créé un robot Line qui devine le sexe et l'âge d'une personne à partir de l'image
J'ai fait quelque chose avec python qui NOW LOADING se déplace de gauche à droite sur le terminal
J'ai fait un simple blackjack avec Python
J'ai créé un modèle de projet Python générique
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber
[Python] J'ai créé un utilitaire qui peut accéder au type dict comme un chemin
J'ai créé un konoha de bibliothèque qui fait passer le tokenizer à une belle sensation
ConSinGAN: J'ai essayé d'utiliser le GAN qui peut être généré à partir d'une image
J'ai fait un module PyNanaco qui peut charger des crédits nanaco avec python
Depuis que j'ai commencé à travailler à des moments différents, j'ai créé un Bot qui me dit l'heure de quitter le travail
J'ai créé un LINE BOT qui renvoie une image de riz terroriste en utilisant l'API Flickr
Je souhaite créer une file d'attente prioritaire pouvant être mise à jour avec Python (2.7)
J'ai fait un simple portefeuille de Bitcoin avec pycoin
J'ai créé un outil pour générer du Markdown à partir du fichier JSON Scrapbox exporté
Je ne pouvais pas m'échapper du futon, alors j'ai fabriqué une machine à éplucher les futons entièrement automatique.
En Python, j'ai créé un LINE Bot qui envoie des informations sur le pollen à partir des informations de localisation.
J'ai fait un simple lecteur RSS ~ Edition C ~
J'ai créé une application Twitter qui décrypte les caractères de pré-connexion avec heroku (échec)
Convertir des images du SDK FlyCapture en un formulaire pouvant être utilisé avec openCV
[Python] J'ai créé un système pour introduire "la recette que je veux vraiment" depuis le site de recettes!
[Django] Appuyez sur une commande que vous avez effectuée à partir du processus qui s'exécute sur manage.py.
J'ai essayé de faire une application mémo qui peut être pomodoro, mais un enregistrement de réflexion
L'histoire selon laquelle sendmail qui peut être exécuté dans le terminal ne fonctionnait pas avec cron
[Python / C] J'ai créé un appareil qui fait défiler sans fil l'écran d'un PC à distance.
Un mécanisme pour appeler des méthodes Ruby à partir de Python qui peut être fait en 200 lignes
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber (édition Google Calendar)
J'ai créé mon propre middleware Django afin de pouvoir accéder aux informations de demande de n'importe où
Quantité d'entités pouvant être extraite des données de séries chronologiques
J'ai créé une VM qui exécute OpenCV pour Python
D'un livre que les programmeurs peuvent apprendre ... (Python): Pointer
Un mémo que j'ai touché au magasin de données avec python
J'ai fait une commande pour marquer le clip de la table
Lister les classes qui peuvent être référencées par ObjCClass
〇✕ J'ai fait un jeu
J'ai créé un outil pour générer automatiquement un diagramme de transition d'état pouvant être utilisé à la fois pour le développement Web et le développement d'applications
Comment configurer un serveur SMTP simple qui peut être testé localement en Python
Étant donné que ImageDataGenerator ne peut plus être utilisé, une histoire sur la création d'une classe d'extension de données pour tensorflow> = 2.0
[Python] Un programme pour trouver le nombre de pommes et d'oranges qui peuvent être récoltées
Convertir les données de maillage exportées de SpriteUV2 dans un format pouvant être importé par Spine
Une histoire qui a trébuché lorsque j'ai créé un bot de chat avec Transformer
[Python] Poésie que j'ai commencé & Impression que j'ai passé de Pipenv à la poésie
J'ai fait un jeu de frappe simple avec tkinter de Python