You are not logged in.
Eheh, nice, maybe i can print it everytime she gives a wrong answer, thanks
Help me to improve ssh-rdp !
Retroarch User? Try my koko-aio shader !
Offline
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
Ok, interesting...thanks.
Offline
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
Inofficial first vice president of the Rust Evangelism Strike Force
Offline
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
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
Evil, evil eval.
"evilisher"
Evil, evilisher, eval.
#!/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
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
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
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
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
Para todos todo, para nosotros nada
Offline