You are not logged in.

#3351 2020-04-03 17:08:18

kokoko3k
Member
Registered: 2008-11-14
Posts: 1,975

Re: Post your handy self made command line utilities

Eheh, nice, maybe i can print it everytime she gives a wrong answer, thanks smile

Offline

#3352 2020-04-03 17:11:00

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 23,439
Website

Re: Post your handy self made command line utilities

Teckk, that seems needlessly complex:

#!/bin/sh

printf "     "
printf " %3d " $(seq 0 15)
printf \\n
for i in $(seq 0 15); do
	printf "\033[0m %3d " $i
	for j in $(seq 0 15); do
		printf "\033[%d;30m %3d " $((43+j%3)) $((i * j))
	done
	printf "\033[0m\n"
done

Or a bit more flexible, optionally pass a min and max number as parameters:

#!/bin/sh

min=${1:-0}
max=${2:-15}

printf "     "
printf " %3d " $(seq $min $max)
printf \\n
for i in $(seq $min $max); do
	printf "\033[0m %3d " $i
	for j in $(seq $min $max); do
		printf "\033[%d;30m %3d " $((43+j%3)) $((i * j))
	done
	printf "\033[0m\n"
done

Of course the layout would break if the max is greater than 31.

Last edited by Trilby (2020-04-03 17:13:56)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3353 2020-04-03 18:12:30

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

Ok, interesting...thanks.

Offline

#3354 2020-04-03 18:29:25

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

Lets have another one, since we are bored sitting at home...need something to do. I have a few scripts saved from projects that I worked on.

Plotting 3 sinusoidal waves 90 degrees out of phase with each other.

#! /usr/bin/env bash

#Plotting 3 sinusoidal waves 90 deg out of phase.
#Terminal need to be at least 80 char wide/30 lines tall.

a=0
b=90
c=180
step=10
hplot=5
cline=12
amp=11
PI=3.14159

clear
printf "%45s %s\n %s\n" "Sine wave plot"

while [ $a -le 720 ]; do

    vplot1=$(awk "BEGIN{ printf \"%.12f\", \
                ((sin($a*($PI/180))*$amp)+$cline)}")
                
    vplot2=$(awk "BEGIN{ printf \"%.12f\", \
                ((sin($b*($PI/180))*$amp)+$cline)}")
                
    vplot3=$(awk "BEGIN{ printf \"%.12f\", \
                ((sin($c*($PI/180))*$amp)+$cline)}")
                
    vplot1=$((24 - ${vplot1/.*}))
    vplot2=$((24 - ${vplot2/.*}))
    vplot3=$((24 - ${vplot3/.*}))
    
    tput bold
    tput setaf 1
    printf "\x1B["$vplot1";"$hplot"f*"
    tput setaf 4
    printf "\x1B["$vplot2";"$hplot"f*"
    tput setaf 2
    printf "\x1B["$vplot3";"$hplot"f*"
    tput sgr0
    printf "\x1B[26;1fPlot for "$a" degrees."
    
    sleep 0.05
    a=$((a + step))
    b=$((b + step))
    c=$((c + step))
    hplot=$((hplot + 1))
    
done
echo -e "\n"

Offline

#3355 2020-04-03 19:34:55

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 23,439
Website

Re: Post your handy self made command line utilities

I don't understand half the complexity there (like having awk output a lot of decimal places but then discarding all that with bash string manipulation which effectively 'floors' each value rather than rounding), but this does about the same thing, you can adjust the numbers in the awk script to make it exactly how you want:

#!/bin/sh

start=0
step=10
end=720
height=24
sx=5

clear
printf %45s "Sine wave plot"

seq $start $step $end | \
awk '
BEGIN { deg2rad = atan2(0,-1) / 180; mult = '$height' / 2; offset = '$height' / 2 + 3; }
// {
	printf "%d %.0f %.0f %.0f\n", $0,
		offset + mult * sin($0 * deg2rad),
		offset + mult * sin(($0 + 90) * deg2rad),
		offset + mult * sin(($0 + 180) * deg2rad);
}' | \
while read x y1 y2 y3; do
#printf "%d\n" $y1
	printf '\033[%d;%dH\033[3%dm*' $y1 $sx 1 $y2 $sx 4 $y3 $sx 2
	printf '\033[%d;0H\033[0mPlot for %d degrees\n' $((height + 5)) $x;
	sleep 0.05
	sx=$((sx+1))
done

Note mine uses 1 instance of awk and 2 subshells total while yours used 3 awk instances and 3 subshells for every x coordinate, that's 216 subshells and 216 invocations of awk.  That's 215 too many!

(added bonus, no bashisms).

edit: added 'height' variable to easily customize it.  The resulting height is actually a bit over 2*$height (plot is 2*$height, then there are captions).

Last edited by Trilby (2020-04-03 20:09:32)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3356 2020-04-03 21:06:31

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

Thanks for that.

printf '\033[%d;0H\033[0mPlot for %d degrees\n' $((height + 5)) $x

This causes it to scroll a line with every print. Remove \n

Offline

#3357 2020-04-03 21:49:37

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 23,439
Website

Re: Post your handy self made command line utilities

It resets the position on every print as well, so it only affects the placement of the cursor.  I find it nicer with the cursor out of the way.  Of course there's an ansi sequence for hiding the cursor as well.

EDIT: ah, it does scroll if your "height" setting is set just to fill the screen.

Last edited by Trilby (2020-04-03 21:51:07)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3358 2020-04-09 03:20:00

salonkommunist
Member
From: Germany
Registered: 2020-02-18
Posts: 25

Re: Post your handy self made command line utilities

I recently found a script on reddit which makes it possible to integrate tabbing functionality into the bspwm window manager. While I liked what the script does, I did not like its implementation one bit; I found it clunky and hardly readable, so I decided to rewrite it from scratch. While at it, I added some functionality and removed the possibility to tab one single window, because I found that rather pointless.

This is my version of the script:

#!/bin/bash
## alltab-bspwm.sh brings tabbing functionality to bspwm.
## It relies on tabbed, xdotool, and xwininfo.

currentWID=$(bspc query -N -n focused)
case $1 in
    east|north|south|west)  targetWID=$(bspc query -N -n $1) || exit 1
                            if bspc query -T -n focused | grep -q tabbed ; then
                                if bspc query -T -n $1 | grep -q tabbed ; then
                                    if [ $(xwininfo -id $currentWID -children | wc -l) -eq 9 ] ; then
                                        xdotool windowreparent $(xwininfo -id $currentWID -children | awk 'NR==8 {print $1}') $(xwininfo -root | awk '/Window id:/ {print $4}')
                                    fi
                                    xdotool windowreparent $(xwininfo -id $currentWID -children | awk 'NR==7 {print $1}') $targetWID
                                else
                                    bspc config -n $targetWID border_width 0
                                    xdotool windowreparent $targetWID $currentWID
                                fi
                            else
                                if bspc query -T -n $1 | grep -q tabbed ; then
                                    bspc config -n $currentWID border_width 0
                                    xdotool windowreparent $currentWID $targetWID
                                else
                                    tabbedWID=$(tabbed -c -d | tail -n 1)
                                    bspc config -n $currentWID border_width 0
                                    bspc config -n $targetWID border_width 0
                                    xdotool windowreparent $currentWID $tabbedWID
                                    xdotool windowreparent $targetWID $tabbedWID
                                fi
                            fi ;;
    detach)                 if bspc query -T -n focused | grep -q tabbed ; then
                                rootWID=$(xwininfo -root | awk '/Window id:/ {print $4}')
                                if [ $(xwininfo -id $currentWID -children | wc -l) -eq 9 ] ; then
                                    xdotool windowreparent $(xwininfo -id $currentWID -children | awk 'NR==8 {print $1}') $rootWID
                                fi
                                xdotool windowreparent $(xwininfo -id $currentWID -children | awk 'NR==7 {print $1}') $rootWID
                            fi ;;
    *)                      echo "Usage: ./alltab-bspwm.sh [east|north|south|west|detach]"
                            echo "You probably want to add something like this to your sxhkdrc file:"
                            echo "# Tabbing functionality for bspwm"
                            echo "super + t; {h,j,k,l,d}"
                            echo "    /path/to/alltab-bspwm.sh {west,south,north,east,detach}" ;;
esac

Last edited by salonkommunist (2020-04-09 13:26:54)

Offline

#3359 2020-04-11 10:25:11

singeinfini
Member
Registered: 2020-04-11
Posts: 4

Re: Post your handy self made command line utilities

I wrote a similar but less functional script for i3wm using dmenu, wmctrl and xorg-xprop. It displays the window class names in the dmenu bar, eventually adding a number to distinguish between windows with the same name. It can handle windows in scratchpad too.

#!/bin/bash
dmenu_switch() {
  declare -A wid
  desktop=$(/usr/bin/xprop -root _NET_CURRENT_DESKTOP | tail -c2)

  while read -r WID; do
    WCLASS=$(/usr/bin/xprop -id "${WID}" WM_CLASS | cut -d' ' -f4- | tr -d \")
    wid[$WCLASS]+="${wid[$WCLASS]:+ }${WID}"

  done <<<"$(/usr/bin/wmctrl -l |\
    grep -Eo "0x[0-9a-f]{8}\s*(${desktop}|-1)" | cut -d' ' -f1)" 

  ((${#wid[@]})) || exit

  selected_app=$(
    for app in "${!wid[@]}"; do
      if [ ${#wid[$app]} -gt 10 ]; then
        idx=1
        for _ in ${wid[$app]}; do
          echo "${app} ${idx}"
          ((idx++))
        done
      else
        echo "${app}"
      fi
    done | /usr/bin/dmenu -i -p "Swich to" 
  )

  if [[ "${selected_app}" =~ ^.*[[:space:]][0-9]*$ ]]; then
    idx=$((${selected_app##*[[:space:]]}-1))
    read -r -a ids <<< "${wid[${selected_app%%[[:space:]][0-9]*}]}"
    selected_wid="${ids[$idx]}"
  else
    selected_wid="${wid[$selected_app]}"
  fi

  ((selected_wid)) && \
    /usr/bin/i3-msg "[id=${selected_wid}]" focus >/dev/null 2>&1
}

Offline

#3360 2020-04-11 12:45:38

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

Very basic text only web browser.
Uses python3, tkinter, urllib, bs4 or htm2text

The browser isn't special, w3m or lynx work better, it demonstrates how to make a GUI with tkinter, create widgets, place them using frames, get input from them, place output into them, save content to file.

There is nothing stopping the viewer from placing the elements in a grid, putting some forward/back buttons on it, using tkinter.ttk instead of tkinter to colorize it, or using the framework for something else.

#! /usr/bin/python

#Basic text web browser

from tkinter import *
from urllib import request
from bs4 import BeautifulSoup
from html2text import html2text, HTML2Text
from youtube_dl import YoutubeDL

#User agent for requests
agent = ('Mozilla/5.0')
        
#Make request header
user_agent = {'User-Agent': agent,
            'Accept': 'text/html,application/xhtml+xml,'
            'application/xml;q=0.9,*/*;q=0.8',
            'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
            'Accept-Encoding': 'none',
            'Accept-Language': 'en-US,en;q=0.8',
            'Connection': 'keep-alive'}

#homePage = 'file:///path/to/Bookmarks.html'
homePage = 'https://bbs.archlinux.org/viewtopic.php?id=56646&p=135'
#homePage = 'https://www.youtube.com/watch?v=5Q5g-krgDnk'

def TkBrowser():
    #Load the page with urllib
    def loadPage():
        req = request.Request(entry.get(), 
                            data=None, headers=user_agent)
        page = request.urlopen(req)
        return page
        
    #Get page source
    def viewSource():
        text.delete(1.0, END)
        pSource = loadPage()
        html = pSource.read()
        text.insert(1.0, html)
        return html
        
    #Write source code to file
    def saveSource():
        getHtml = viewSource().splitlines()
        sSource = '\n'.join(line.decode('utf-8') for line in getHtml)
        with open('TkBSource.html', 'a') as f:
            f.write(sSource)
            
    #Get text of page with soup
    def textBrowse():
        text.delete(1.0, END)
        get = loadPage()
        soup = BeautifulSoup(get, features='lxml')
        #Kill all script and style elements
        for s in soup(["script", "style"]):
            s.extract()
        txt = '\n'.join(soup.get_text().splitlines())
        text.insert(1.0, txt)
        return txt
        
    #Get text of page with html2text
    def textBrowse2():
        text.delete(1.0, END)
        pSource = loadPage()
        html = pSource.read()
        noLinks = HTML2Text()
        noLinks.ignore_links = True
        txt = noLinks.handle(html.decode('utf-8'))
        text.insert(1.0, txt)
        
    #Save text of page to file
    def savePage():
        getPage = textBrowse()
        with open('TkBText.txt', 'w') as f:
            f.write(getPage)
        
    #Get links on page with soup
    def pageLinks():
        text.delete(1.0, END)
        getP = loadPage()
        soup = BeautifulSoup(getP, 'lxml')
        hrefTags = soup.find_all(href=True) 
        links = [tag.get('href') for tag in hrefTags]
        linkList = '\n'.join(l for l in links if l)
        text.insert(1.0, linkList)
        return linkList
        
    #Save links to file
    def saveLinks():
        getLinks = pageLinks()
        with open('TkBLinks.txt', 'w') as f:
            f.write(getLinks)
            
    #Get Utube video urls
    def getUtube():
        text.delete(1.0, END)
        ulist = []
        yt = YoutubeDL()
        info = yt.extract_info(entry.get(), download=False)
        ulist.append(info['title'])
        ulist.append('')
        ulist.append(info['description'])
        ulist.append('')
        try:
            for i in info['formats']:
                ulist.append(i['format_id'])
                ulist.append(i['fragment_base_url'])
                ulist.append('')
                utList  = '\n'.join(ulist)
        except:
            pass
        text.insert(1.0, utList)
        return utList
        
    #Save Utube url's to file
    def saveUtube():
        getTube = getUtube()
        with open('TkBUtube.txt', 'w') as f:
            f.write(getTube)
            
    #Make a window
    browser = Tk()
    browser.title('PyTk Browser')
    #Window size
    browser.geometry('1200x900')
    fontSize = ('Arial', 18)
    bg='grey20'
    fg='white'
    bw=3
    
    #Make Frames
    top = Frame(browser)
    bottom = Frame(browser)
    top.pack(side=TOP)
    bottom.pack(side=BOTTOM, fill=BOTH, expand=True)
 
    #Make menubar
    menubar = Menu(browser)
    browser.config(menu=menubar, bg=bg)
    menubar.config(font=fontSize, bd=bw, bg=bg, fg=fg)
    
    #Make menu entries
    #Load menu
    loadmenu = Menu(menubar, tearoff=0)
    loadmenu.config(
        font=fontSize, bd=bw, bg=bg, fg=fg)
    loadmenu.add_command(
        label="Get page text with Beautiful Soup", command=textBrowse)
    loadmenu.add_command(
        label="Get page text with Html2text", command=textBrowse2)
    loadmenu.add_command(
        label="Save page text to file", command=savePage)
        
    #Source menu
    sourcemenu = Menu(menubar, tearoff=0)
    sourcemenu.config(
        font=fontSize, bd=bw, bg=bg, fg=fg)
    sourcemenu.add_command(
        label="View page source code", command=viewSource)
    sourcemenu.add_command(
        label="Save page source code to file", command=saveSource)
        
    #Links menu                                            
    linksmenu = Menu(menubar, tearoff=0)
    linksmenu.config(
        font=fontSize, bd=bw, bg=bg, fg=fg)
    linksmenu.add_command(
        label="View page links", command=pageLinks)
    linksmenu.add_command(
        label="Save page links to file", command=saveLinks)
        
    #UTube menu
    utubemenu = Menu(menubar, tearoff=0)
    utubemenu.config(
        font=fontSize, bd=bw, bg=bg, fg=fg) 
    utubemenu.add_command(
        label="View utube url's", command=getUtube)
    utubemenu.add_command(
        label="Save utube url's to file", command=saveUtube)

    #Make a url entry widget
    entry = Entry(browser)
    label = Label(text='url')
    label.config(font=fontSize, bg=bg, fg=fg, highlightthickness=3)
    entry.config(font=fontSize, width=80, bd=bw, 
                        highlightcolor='blue', highlightthickness=3)
    #Bind enter key to textBrowse()
    entry.bind('<Return>', lambda event=None: textBrowse())
    entry.insert(END, homePage)
    
    #Make a scroll bar
    scroll = Scrollbar(browser)
    scroll.config(width=25, bd=bw, bg=bg, troughcolor=fg)

    #Make text widget
    text = Text(browser, yscrollcommand=scroll.set)
    text.config(font=fontSize, bd=bw, bg='white', fg='black', 
                        highlightcolor='blue', highlightthickness=3)
    scroll.config(command=text.yview)
    
    #Place widgets
    menubar.add_cascade(label="Load", menu=loadmenu)
    menubar.add_cascade(label="Source", menu=sourcemenu)
    menubar.add_cascade(label="Links", menu=linksmenu)
    menubar.add_cascade(label="UTube", menu=utubemenu)
    entry.pack(in_=top, side=LEFT)
    label.pack(in_=top, side=RIGHT)
    scroll.pack(in_=bottom, side=RIGHT, fill=Y)
    text.pack(in_=bottom, side=TOP, fill="both", expand=True)

    browser.mainloop()

if __name__ == "__main__":
    TkBrowser()

https://docs.python.org/3/
https://docs.python.org/3/library/tk.html
https://docs.python.org/3/library/urllib.html
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
https://pypi.org/project/html2text/

Last edited by teckk (2020-04-11 12:46:46)

Offline

#3361 2020-04-11 15:15:24

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

A simplified version of a web page request dump script.
Uses python3, webengine, PyQt5

req_dump.py

#! /usr/bin/python

#Print web page requests to terminal and file.
#Needs Qt5-WebEngine and PyQt5

#Import only what you need
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
from PyQt5.QtWebEngineWidgets import (QWebEngineView, 
                            QWebEnginePage, QWebEngineProfile)
#Get web page url                            
#URL = input('Enter/paste url to inspect: ')
URL = 'https://www.youtube.com/watch?v=5Q5g-krgDnk'

#User agent for requests
agent = ('Mozilla/5.0 (Windows NT 10.1; x86_64; rv:74.0) '
            'Gecko/20100101 Firefox/74.0')

#Intercept requests, print to terminal and file
class UrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def interceptRequest(self, info):
        req = info.requestUrl()
        req2str = req.toString()
        print('\n', req2str)
        #Append info to log file
        with open('req_dump.log', 'a') as f:
            f.write(req2str + '\n\n')

class WebEnginePage(QWebEnginePage):
    def acceptRequest(self):
        return QWebEnginePage.acceptRequest(self)

#Make a browser window, load page
if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    interceptor = UrlRequestInterceptor()
    profile = QWebEngineProfile()
    profile.setHttpUserAgent(agent) #Set user agent
    profile.setRequestInterceptor(interceptor)
    
    browser = QWebEngineView()
    page = WebEnginePage(profile, browser)
    page.setUrl(QUrl(URL))
    page.setZoomFactor(1.2) #Zoom
    
    browser.setPage(page)
    browser.setMinimumSize(1000,800) #Browser size
    browser.show()
    sys.exit(app.exec_())

   
A simplified version of a web page cookie dump script.

cookie_dump.py

#!/usr/bin/python

#Dumps cookies to terminal

import sys
from PyQt5.QtNetwork import QNetworkCookie
from PyQt5.QtWebKitWidgets import QWebView
from PyQt5.QtCore import QUrl, QByteArray, Qt
from PyQt5.QtWidgets import (QMainWindow, QWidget, 
                                    QApplication, QTextEdit)
from PyQt5.QtWebEngineWidgets import (QWebEngineView, 
                            QWebEngineProfile, QWebEnginePage)

#url = input('Enter/Paste url for cookies: ')
url = 'https://www.youtube.com/watch?v=5Q5g-krgDnk'

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        QMainWindow.__init__(self, *args, **kwargs)
        self.webview = QWebEngineView()
        profile = QWebEngineProfile("storage", self.webview)
        cookie_store = profile.cookieStore()
        cookie_store.cookieAdded.connect(self.onCookieAdded)
        self.cookies = []
        webpage = QWebEnginePage(profile, self.webview)
        self.webview.setPage(webpage)
        self.webview.load(QUrl(url))
        self.setCentralWidget(self.webview)

    def onCookieAdded(self, cookie):
        for c in self.cookies:
            if c.hasSameIdentifier(cookie):
                return
        self.cookies.append(QNetworkCookie(cookie))
        self.toJson()

    def toJson(self):
        cookies_list_info = []
        for c in self.cookies:
            data = {
            "name": bytearray(c.name()).decode(), 
            "domain": c.domain(), 
            "value": bytearray(c.value()).decode(),
            "path": c.path(), 
            "expirationDate": c.expirationDate().toString(Qt.ISODate), 
            "secure": c.isSecure(),
            "httponly": c.isHttpOnly()
            }
            cookies_list_info.append(data)
        print('\n\n' 'Cookie dictionary:')
        print(cookies_list_info)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

   
If you don't know what these can be used for, then this isn't for you. Thanks for looking.

Offline

#3362 2020-04-11 22:19:45

Awebb
Member
Registered: 2010-05-06
Posts: 5,428

Re: Post your handy self made command line utilities

salonkommunist wrote:

While at it, I added some functionality and removed the possibility to tab one single window, because I found that rather pointless.

The point is having a reproducible interface with tabs where tabs usually are, regardless of the number of tabs.

Offline

#3363 2020-04-12 03:21:28

salonkommunist
Member
From: Germany
Registered: 2020-02-18
Posts: 25

Re: Post your handy self made command line utilities

Awebb wrote:

The point is having a reproducible interface with tabs where tabs usually are, regardless of the number of tabs.

I see how that would be desirable for some users. I personally prefer only two or more windows to be tabbed, so I implemented it this way. The behavior is easy enough to change, so I don't think this particular decision is a big deal anyway.

Offline

#3364 2020-04-12 10:55:38

Awebb
Member
Registered: 2010-05-06
Posts: 5,428

Re: Post your handy self made command line utilities

salonkommunist wrote:
Awebb wrote:

The point is having a reproducible interface with tabs where tabs usually are, regardless of the number of tabs.

I see how that would be desirable for some users. I personally prefer only two or more windows to be tabbed, so I implemented it this way. The behavior is easy enough to change, so I don't think this particular decision is a big deal anyway.

No big deal. I just wanted to provide a possible point, since it didn't seem to occur to you. I have no horse in that race.

Offline

#3365 2020-04-15 16:53:12

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

Forced to stay home with my familiy, my 7 years old baby is forced to study here

Kid game. Enter the colors before the clock runs out. The timer will run faster if you enter a wrong answer. The answer is given to them at first, if they figure that out. Age range 3-8 I would say. Teaches colors and typing. Modify the text= strings into Italian if you wish. Let me see, that would be lines 35 42 46 51 54 68 73

#!/usr/bin/python 

#Enter the color you see game.

from tkinter import *
from random import shuffle
  
color = ['Red','Orange','Yellow','Blue','Green','Pink',
        'White','Purple','Brown','Gray', 'Maroon', 'Cyan',
        'Tan', 'Violet']

class colorGame():
    def __init__(self, score, timeleft, hurry):
        super(colorGame, self).__init__()
        
        self.score = score
        self.timeleft = timeleft
        self.hurry = hurry

        def start(event): 
            if self.timeleft > 0:
                colors()
            if self.score == score:
                count()
          
        def colors():
            if self.timeleft > 0: 
                if ent.get().lower() == color[1].lower(): 
                    self.score += 1
                       
                ent.delete(0, END) 
                shuffle(color)
                colorLabel.config(fg=str(color[1]), 
                                            text=str(color[0]))
                scoreLabel.config(text="\nScore: " 
                                            + str(self.score))
                                             
        def count():
            t=[]
            for c in color:
                t.append(c)
            hurryLabel.config(text='\nColors are ' + str(t), 
                                            font=fontSize3)
            if self.timeleft > 0:
                self.timeleft -= 1
                timeLabel.config(text="\nTime left: "
                        + str(self.timeleft)+'\n', font=fontSize)
                timeLabel.after('1000', count)
                        
            if self.timeleft in range(1, 30):
                hurryLabel.config(text="\nHurry!", font=fontSize)
                    
            if self.timeleft == 0:
                hurryLabel.config(text="\nDone! " 
                + "Can you get a better score?", font=fontSize)

        bg = 'black'
        fg = 'white'
        root = Tk()
        root.config(bg=bg)
        root.title("Enter The Color Game") 
        root.geometry("1400x700")
        fontSize = ('Monospace', 34)
        fontSize2 = ('Monospace', 80)
        fontSize3 = ('Monospace', 12) 
         
        inst = Label(root,
            text="Enter color of words before the clock runs out",
            font=fontSize, bg=bg, fg=fg) 
        inst.pack()
          
        scoreLabel = Label(root,
            text="Press Enter to start", font=fontSize, bg=bg, fg=fg) 
        scoreLabel.pack() 
          
        timeLabel = Label(root, text = "\nTime left: " +
                        str(timeleft), font=fontSize, bg=bg, fg=fg) 
        timeLabel.pack() 
          
        colorLabel = Label(root, font=fontSize2, bg=bg, fg=fg)
        colorLabel.pack() 

        ent = Entry(root)
        ent.config(font=fontSize)
        ent.pack() 
        ent.focus_set() 
        
        hurryLabel = Label(root, font=fontSize, bg=bg, fg=fg)
        hurryLabel.pack()
        
        root.bind('<Return>', start)
        root.mainloop() 
    
if __name__ == "__main__":
    
    score = 0
    #Set clock times here
    timeleft = 60
    hurry = 30
    colorGame(score, timeleft, hurry)

Offline

#3366 2020-04-25 16:18:30

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

Little tkinter calculator that scrolls and logs to file. All it needs is python3. Change it if you are bored.

#!/usr/bin/python

#tkinter calculator

from tkinter import *

class Calc(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.option_add("*Font", "Monospace 30 bold")
        self.config(bg='green')
        self.pack(expand=YES, fill=BOTH)
        self.master.title("Tk Calculator")
        self._display()
        self.listbox = Listbox(
            self, width=30, relief=SUNKEN, bd=6, 
            highlightcolor='yellow', highlightthickness=2, 
            highlightbackground='black')
        self.listbox.pack()
        self.count = 0

    def _display(self):
        display = StringVar()
        self.entry = Entry(
            self, relief=SUNKEN, bd=6, textvariable=display, 
            highlightcolor='yellow', highlightthickness=2, 
            highlightbackground='black', justify='center')
        self.entry.pack(side=TOP)
        self.entry.focus()
        self.master.bind("<KP_Enter>", lambda x: self.calc(display))
        self.master.bind("<Return>", lambda x: self.calc(display))
        self.master.bind("<Escape>", lambda x: display.set(""))
    
    def calc(self, display):
        try:
            dis = eval(display.get())
            if str(display.get()).isdigit:
                txt = (display.get() + " = " + str(dis))
                self.listbox.insert(END, txt) 
                with open('TkCalc.txt', 'a') as f:
                    f.write(txt + '\n')
                display.set("")
                self.count += 1      
        except NameError as e:
            display.set("!Integer Press Esc.")
        if self.count > 10:
            self.listbox.delete([0])
                
if __name__ == '__main__':
    Calc().mainloop()
2+3 = 5
27*(9/5)+32 = 80.6
3.1415927*(21**2) = 1385.4423807
(2*3.1415927)*21 = 131.9468934
(80-32)*.56 = 26.880000000000003
25**.5 = 5.0
12*(10**2) = 1200
(6/9)+(3*2) = 6.666666666666667

Offline

#3367 2020-04-25 19:48:31

schard
Member
From: Hannover
Registered: 2016-05-06
Posts: 751
Website

Re: Post your handy self made command line utilities

Evil, evil eval.
And you execute it even before testing whether it just contains digits.
You didn't write a calculator, but a python terminal emulator, that just displays results, if they are a number.
Harmless example: Start the script in a terminal and enter print(dir()).

Also

if str(display.get()).isdigit:

will alwys be true, since you're testing whether a string's method isdigit is truthy.
str.isdigit is not a property. If you want to test it, you need to call it:

'42'.isdigit()
'foobar'.isdigit()

The entire script is buggy as hell.
If you would implement the check correctly, the calculator won't display any results anymore, apart from plain numerical inputs.

Last edited by schard (2020-04-25 20:09:13)

Offline

#3368 2020-04-26 12:52:29

teckk
Member
Registered: 2013-02-21
Posts: 368

Re: Post your handy self made command line utilities

Yes, I understand the risks of eval. It's on the same machine that a user could open a python shell and do what they wish though.

Do you think that this is safer?
Using ast to verify that the expression only contains a whitelist of certain types and operators before passing it to eval()

from ast import *

    def calc(self, display):
        try:
            dis = display.get()
            tree = parse(dis, mode='eval')
        except SyntaxError:
            display.set("Syntax Error")
            return
            
        if not all(isinstance(node, (Expression, UnaryOp, unaryop,
            BinOp, operator, Num)) for node in walk(tree)):
            display.set("Non Integer")
            return
            
        result = eval(compile(tree, filename='', mode='eval'))
        txt = (str(dis) + " = " + str(result))
        self.listbox.insert(END, txt)
        display.set("")
        with open('TkCalc.txt', 'a') as f:
            f.write(txt + '\n')

           

You didn't write a calculator, but a python terminal emulator

Yes, a little handier than a python shell, and small.

Offline

#3369 2020-04-26 13:13:54

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 23,439
Website

Re: Post your handy self made command line utilities

teckk wrote:

Yes, a little handier than a python shell

In what way?  Certainly this is subjective, but I'm curious in what way this actually is handier than a terminal opening to an interactive python shell, perhaps even with a customized prompt.  The difference is in the colors perhaps - which are easily configured in the terminal and python prompt, and also in the fact that the input line is always at the top ... which I don't see benefit in, but if you do, you could also do that with a python prompt.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3370 2020-04-26 14:37:56

seth
Member
Registered: 2012-09-03
Posts: 14,795

Re: Post your handy self made command line utilities

schard wrote:

Evil, evil eval.

"evilisher"
Evil, evilisher, eval.
tongue

#!/bin/sh
# funcs.bc and logic.bc are from http://phodd.net/gnu-bc/
# xrm override because german numpads - and math - uses a comma instead of a dot
# rlwrap to get a prompt
# IBM 3270 because it looks calculatish…whatever

FONT="IBM 3270 Narrow"
FONT_SIZE=20

xterm -xrm 'xterm.vt100.translations: #override <Key>KP_Delete:string(.)' -bc +uc \
       -b 16 -title Calculator -fa "$FONT" -fs $FONT_SIZE -geometry 40x10 -e rlwrap \
       -pyellow -a -S'= ' bc -ql ~/.local/share/bc/code/funcs.bc ~/.local/share/bc/code/logic.bc

Offline

#3371 2020-04-26 14:53:08

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 23,439
Website

Re: Post your handy self made command line utilities

If we have bc, this would pretty much replicate the behavior of teckk's tkinter program in a terminal.  You could add more ansi codes for more "decoration" even adding box drawing if around input and ouput if you wanted.

#!/bin/sh

printf '\033[2J\033[0;0H\n\033[s\033[A\033[34;1m'

while read line; do
	case "$line" in
		q*) break ;;
		*) printf '\033[0m\033[u%s = %s\n\033[s\033[0;0H\033[K\033[34;1m' "$line" "$(echo "$line" | bc)" ;;
	esac
done
printf '\033[u'

Last edited by Trilby (2020-04-26 14:54:09)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3372 2020-05-04 16:30:31

zpg443
Member
Registered: 2016-12-03
Posts: 52

Re: Post your handy self made command line utilities

In case this has not been posted already...a one-liner to get the total size of all installed packages:

awk '/%SIZE%/ {getline; size+=$1; } END { print size / (1024**3) " GiB"; }' /var/lib/pacman/local/*/desc

Offline

#3373 2020-05-23 10:37:32

salonkommunist
Member
From: Germany
Registered: 2020-02-18
Posts: 25

Re: Post your handy self made command line utilities

This is a simple script that does a fuzzy file search across the user's home directory and passes the selected file to an application to open it with:

#!/bin/bash
fuzz=$(find ~ -type f | rofi -dmenu -i -p "Open file")
test -z $fuzz && exit
filetype=$(echo $fuzz | awk -F '.' '{print $NF}')
shopt -s nocasematch
case $filetype in
    pdf|epub)                                               zathura "$fuzz" & ;;
    doc|docx|odt|ppt|xls)                                   libreoffice "$fuzz" & ;;
    wav|mp3|flac|mp4|avi|mkv|mov|mpg|mpeg|3gp|flv|webm)     mpv "$fuzz" & ;;
    psd|xcf)                                                gimp "$fuzz" & ;;
    html)                                                   qutebrowser "$fuzz" & ;;
    jpg|jpeg|gif|bmp|png|tif|tiff)                          qiv -B "$fuzz" & ;;
    svg)                                                    inkscape "$fuzz" & ;;
    rar|7z|zip|gz|tar)                                      engrampa "$fuzz" & ;;
    *)                                                      urxvt -e vim "$fuzz" & ;;
esac

Offline

#3374 2020-05-23 12:08:38

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 23,439
Website

Re: Post your handy self made command line utilities

filetype=$(echo $fuzz | awk -F '.' '{print $NF}'

What??

case ${fuzz##*.} in
   ...

But really relying on extensions is not going to get you very far, use `file`:

case $(file -b --mime-type $fuzz) in
   video/*) ... ;;
   */pdf) ... ;;

"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3375 2020-05-23 12:44:18

Head_on_a_Stick
Member
From: London
Registered: 2014-02-20
Posts: 5,384
Website

Re: Post your handy self made command line utilities

Offline

Board footer

Powered by FluxBB