Skip to content

Instantly share code, notes, and snippets.

Created September 7, 2012 16:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/3667523 to your computer and use it in GitHub Desktop.
Save anonymous/3667523 to your computer and use it in GitHub Desktop.
Flexibles Menü, zum Handeln spaltengetrennter Dateien
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
import platform
import subprocess
'''
Ermittelt das Betriebssystem mit dem dazugehörigen Programmstarter
und öffnet die an fileopen übergebene Datei damit.
Damit das Modul eingesetzt werden kann, muß dieses importiert werden.
from filestart import fileopen
Der Aufruf lautet:
fileopen(filename)
'''
def filestarter():
'''
Betriebssytem ermitteln und Programmstarter
an Funktion fileopen übergeben.
'''
try:
return {'Windows': 'start',
'Linux': 'xdg-open',
'Darwin': 'open'
}[platform.system()]
except KeyError:
raise RuntimeError(
'Für Ihr Betriebssystem\n%s\nkonnte kein passender Starter ermittelt werden!' % platform.platform())
def fileopen(filename):
'''
Datei mit Programmstarter von Funktion fileopen öffnen.
'''
try:
default_program = filestarter()
except RuntimeError as e:
print(e)
print('\nÖffnen Sie zum Editieren der Datei %s einen Texteditor.\nDie Datei %s befindet sich unter\n%s.' % (filename, chance, os.path.realpath(filename)))
else:
print('Datei %s wird mit dem Standardprogramm\nIhres Betriebsystem zum Editieren geöffnet!' % filename)
process = subprocess.Popen([default_program, filename])
process.wait()
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
import re
import csv
import string
import time
import codecs
from filestart import fileopen
from settingmenu import setting
from settingmenu import LISTFILTER, CASE_SENSITIV, MAX_LINES_PER_SEGMENT
from settingmenu import FILENAME, HEADINGS, AUTOSETTINGS
# Ordner für Daten-Dateien
DATA = '{}/data'.format(os.getcwd())
# Ordner für Daten-Dateien
COPY = '{}/copy'.format(os.getcwd())
# Temporäre Datei
CHANCE = os.path.join(os.path.dirname(__file__), DATA, 'chance.txt')
# Kopie von Datendatei
COPYDATA = os.path.join(os.path.dirname(__file__), COPY,
'copy#{}'.format(os.path.basename(FILENAME)))
# Modulnamen
MODULNAME = 'menu.py'
def datacheck():
if not os.path.exists(COPYDATA):
with codecs.open(FILENAME, 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
write_csv(COPYDATA, [row for row in reader])
return COPYDATA
def datafind():
return {True: COPYDATA,
False: FILENAME
}[os.path.exists(COPYDATA)]
def write_csv(filename, datenpool):
with codecs.open(filename, "w") as zielfile:
writer = csv.writer(zielfile, delimiter="\t", quotechar="^")
return writer.writerows(datenpool)
def writeappend_csv(filename, datenpool):
with codecs.open(filename, "a") as zielfile:
writer = csv.writer(zielfile, delimiter="\t", quotechar="^")
return writer.writerows(datenpool)
def get_formatted_table(menupoint, HEADINGS, contents, spacing=4,
numeration_width=10):
lines = [HEADINGS] + contents
column_widths = [max(len(item) for item in column_items)
for column_items in zip(*lines)]
total_width = sum(column_widths) + (len(column_widths) - 1) * spacing
total_width += numeration_width
dashed_line = total_width * '-'
blank_line = total_width * ' '
numeration_spec = '{{:>{}}}'.format(numeration_width)
column_specs = ['{{:{}}}'.format(width) for width in column_widths]
line_template = numeration_spec + (spacing * ' ').join(column_specs)
headline = line_template.format('Nummer: ', *HEADINGS)
head_items = [dashed_line, headline, blank_line, dashed_line]
formatted_lines = head_items[:]
dataline = dict()
for line_number, text_items in enumerate(contents, 1):
needs_headings = (line_number % MAX_LINES_PER_SEGMENT == 0)
dataline[line_number] = [text_items]
if needs_headings:
formatted_lines.extend(head_items)
numeration_string = '{}: '.format(line_number)
formatted_lines.append(line_template.format(numeration_string,
*text_items))
formatted_lines.append(blank_line)
formatted_lines.append(dashed_line)
print('\n'.join(formatted_lines))
return selection(menupoint, dataline)
def search_base(menupoint):
return search_entry(menupoint, 0)
def search_entry(menupoint, result):
entry = input('\nSuchbegriff: ')
if entry:
print("\nListe wird nach Suchbegriff durchsucht!")
if not type(result) == list:
with open(datafind(), 'r') as infile:
reader = csv.reader(infile, delimiter="\t",
quotechar="^")
contents = [row for row in reader if any(entry in
(x.lower(), x)[CASE_SENSITIV] for x in row)]
elif type(result) == list:
contents = [row for row in result if any(entry in
(x.lower(), x)[CASE_SENSITIV] for x in row)]
if contents:
if len(contents) == 1:
print("\nDie Suche ergab folgendes Ergebnis:")
else:
print("\nDie Suche ergab folgende Ergebnisse:")
return get_formatted_table(menupoint, HEADINGS, contents)
else:
print('\nEs liegen keine Ergebnisse \
\nzu dem Suchbegriff < %s > vor\n' % entry)
else:
print("\nAbbruch, Sie haben keine Eingabe gemacht!")
return
def selection(menupoint, result):
if LISTFILTER == 1 and len(result) > 1:
if input('Möchten Sie das Ergebnis weiter filtern? \
\n< ja / [TASTE] für Abbruch > ') == 'ja':
return search_entry(menupoint, [row for key in
result for row in result[key]])
if menupoint == 'suchen':
return
contents = list()
while True:
try:
selection = int(input(' \
\nZeilennummer oder [TASTE] für Abbruch: '))
if 0 != selection <= len(result):
data = [row for key in result if key == selection
for row in result.get(selection)]
print("\nDatensatz wird zur Auswahl hinzu gefügt!\n")
if os.path.exists(os.path.join(os.getcwd(), CHANCE)):
writeappend_csv(CHANCE, data)
else:
write_csv(CHANCE, data)
contents = [row for key in result if key != selection
for row in result[key]]
if len(result) > 1 and input('Weitere Auswahl treffen? \
\n< ja / [TASTE] für Abbruch > ') == 'ja':
return get_formatted_table(menupoint, HEADINGS,
contents)
break
else:
print('\nFalsche Eingabe, bitte wählen Sie eine Zahl \
\nvon 1 bis %s aus!' % len(result))
except (ValueError, IndexError):
break
if not os.path.exists(os.path.join(os.getcwd(), CHANCE)):
return
elif menupoint == 'ändern':
load(menupoint)
elif menupoint == 'löschen':
if input('\nAusgewählte Datenzeile löschen? \
\n< ja / [TASTE] für Abbruch > ') == 'ja':
print('\nDatenzeile wird gelöscht!')
remove_entry(menupoint)
return
def add_entry(menupoint):
print('')
newdata = list()
newdata = ([(input('Eintrag zu: %s > ' % info))
for info in HEADINGS])
if newdata[0] and newdata[1]:
if input('\nEintrag in die Liste übernehmen? \
\n< %s >\n< ja / [TASTE] für Abbruch > '
% newdata) == 'ja':
print("\nEintrag wird hinzugefügt\n")
writeappend_csv(datacheck(), [newdata])
sort(menupoint)
else:
print("\nEintrag wird nicht hinzugefügt\n")
return
def load(menupoint):
if not os.path.exists(os.path.join(os.getcwd(), CHANCE)):
return search_base(menupoint)
fileopen(CHANCE) # Datei mit Standardprogramm öffnen
with open(CHANCE, 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
olddata = [row for row in reader]
if input('\nÄnderung übernehmen? \
\n< ja / [TASTE] für Abbruch > ') == 'ja':
with open(CHANCE, 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
writeappend_csv(datacheck(), [row for row in reader])
write_csv(CHANCE, olddata)
remove_entry(menupoint)
else:
print("\nDie Änderungen werden nicht übernommen!\n")
return
def remove_entry(menupoint):
if not os.path.exists(os.path.join(os.getcwd(), CHANCE)):
return search_base(menupoint)
olddata = dict()
with codecs.open(CHANCE, 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
for row in reader:
olddata[tuple(row)] = tuple(row)
with codecs.open(datacheck(), 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
newdata = [row for row in reader if not
olddata.get(tuple(row))]
write_csv(datafind(), newdata)
sort(menupoint)
return
def save(menupoint):
if os.path.exists(os.path.join(os.getcwd(), COPYDATA)):
if input('\nMöchten Sie die Datei < %s >, \
\nmit den gemachten Änderungen aktualisieren? \
\n< ja / [TASTE] für Abbruch > ' % FILENAME) != 'ja':
print('\nOriginaldatei < %s > wird nicht mit den \
\ngemachten Änderungen aktualisiert!' % FILENAME)
return
print('\nOriginaldatei < %s > wird mit den \
\ngemachten Änderungen aktualisiert!' % FILENAME)
with codecs.open(COPYDATA, 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
write_csv(FILENAME, [row for row in reader])
return os.remove(COPYDATA)
else:
print('\nEs sind keine Daten zum aktualisieren vorhanden!')
return
def delete(menupoint):
if COPYDATA == datafind():
if input('\nSollen die gemachten Änderungen gelöscht werden? \
\n< ja / [TASTE] für Abbruch > ') == 'ja':
print('\nÄnderungen werden gelöscht!')
os.remove(COPYDATA)
else:
print('\nEs gibt keine Änderungen zum Löschen!')
return
def settings(menupoint):
print(2 * '\n')
setting()
return exit()
def sort(menupoint):
print("\nListe wird sortiert und von \
\ndoppelten Datensätzen bereinigt!\n")
DATAPOOL = datafind()
with open(DATAPOOL, 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
write_csv(DATAPOOL, sorted([row for row in reader]))
return
def quit(menupoint):
print("\nProgramm wird beendet!\n")
print(2 * '\n')
exit()
def hauptmenu():
return handle_menu(menu)
def handle_menu(menu):
while True:
print('\n<<< Hauptmenü >>>')
for index, row in enumerate(menu, 1):
print("{} {}".format(index, row[0]))
try:
if os.path.exists(os.path.join(os.getcwd(), CHANCE)):
os.remove(CHANCE)
choice = int(input("Nummer: ")) - 1
menu[choice][1](menu[choice][2])
except (ValueError, IndexError):
print("\nBitte nur Zahlen im Bereich 1 - {} eingeben\n".
format(len(menu)))
menu = [
["Eintrag suchen", search_base, 'suchen'],
["Eintrag hinzufügen", add_entry, 'hinzufügen'],
["Eintrag ändern", load, 'ändern'],
["Eintrag löschen", remove_entry, 'löschen'],
["Änderungen übernehmen", save, 'speichern'],
["Änderungen löschen", delete, 'löschen'],
["Einstellungen", settings, 'einstellen'],
["Beenden", quit, 'beenden']
]
if __name__ == "__main__":
handle_menu(menu)(int(sys.argv[1]))
Tkinter tkinter Namensänderung von Modul Tkinter, neuer Modulnamen ist tkinter. Statt 'from Tkinter import tkinter' gilt nun 'import tkinter'
execfile() - Ab Python3 entfällt execfile()
from email.MIMEBase import MIMEBase from email.mime.base import MIMEBase Namensänderung von Modul email.MIMEBase, neuer Modulnamen ist email.mime.base
from email.MIMEImage import MIMEImage from email.mime.image import MIMEImage Namensänderung von Modul email.MIMEImage, neuer Modulnamen ist email.mime.image
from email.MIMEMultipart import MIMEMultipart from email.mime.multipart import MIMEMultipart Namensänderung von Modul email.MIMEMultipart, neuer Modulnamen ist email.mime.multipart
from email.MIMEText import MIMEText from email.mime.text import MIMEText Namensänderung von Modul email.MIMEText, neuer Modulnamen ist email.mime.text
print print() print(obj), Objekt muss in Klammern eingeschlossen sein.
raw_input() input() raw_input() wurde durch input() ersetzt.
sys.maxint sys.maxsize Änderung, jedes Vorkommen von sys.maxint wird zu sys.maxsize
tkFont tkinter.font Namensänderung von Modul tkFont, neuer Modulnamen ist tkinter.font
tkMessageBox tkinter.messagebox Namensänderung von Modul tkMessageBox, neuer Modulnamen ist tkinter.messagebox
tkSimpleDialog tkinter.simpledialog Namensänderung von Modul tkSimpleDialog, neuer Modulnamen ist tkinter.simpledialog
xrange range xrange unter Python3 nicht mehr nutzbar
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
import csv
import codecs
import shutil
import tkinter as tk
from tkinter.messagebox import showinfo
from tkinter.filedialog import askopenfilename
from filestart import fileopen
try:
from settings import LISTFILTER, CASE_SENSITIV, MAX_LINES_PER_SEGMENT
from settings import FILENAME, HEADINGS, AUTOSETTINGS
except ImportError:
from copy_settings import LISTFILTER, CASE_SENSITIV, MAX_LINES_PER_SEGMENT
from copy_settings import FILENAME, HEADINGS, AUTOSETTINGS
# Modulnamen
MODULNAME = 'menu.py'
# Datei für benutzerspezifische Einstellungen
SETTING_FILE = 'settings.py'
SETTING_COPY = 'copy_{}'.format(SETTING_FILE)
def write_txt(filename, datenpool):
with codecs.open(filename, "w") as data:
data.write(datenpool + '\n')
def writeappend_txt(filename, datenpool):
with codecs.open(filename, "a") as data:
data.write(datenpool + '\n')
def copy_setting():
return shutil.copy(SETTING_FILE, SETTING_COPY)
def head():
autohead = '#!/usr/bin/python3 \
\n# -*- coding: utf-8 -*-\n'
return write_txt(SETTING_FILE, autohead)
def state_setting(param, text):
state = {1: 'EIN',
0: 'AUS'}[param]
nostate = {0: 'EIN',
1: 'AUS'}[param]
auto = input(text +
'\n< ja > für < %s > / [TASTE] für < %s > ' % (nostate, state))
return {'EIN': 1,
'AUS': 0
}[{True: nostate, False: state}[auto == 'ja']]
def state_value_setting(param, text):
try:
return int(input(text + '\n< Zahlenwert > / [TASTE] für < %s > ' % param))
except ValueError:
return param
def filename_setting():
value = input('\nMöchten Sie die aktuelle Datei < %s > übernehmen? \
\n< ja / [TASTE] für Neue Datei > ' % FILENAME)
filename = FILENAME
if value != 'ja':
filename = tk.filedialog.askopenfilename()
filename = {True: filename,
False: FILENAME}[os.path.isfile(filename)]
print('\nSie haben die Datei < %s > ausgewählt!\n' % filename)
writeappend_txt(SETTING_FILE, 'FILENAME = "{}"'.format(filename))
if filename == FILENAME:
writeappend_txt(SETTING_FILE, 'HEADINGS = {}'.format(HEADINGS))
return
with codecs.open(filename, 'r') as zielfile:
reader = csv.reader(zielfile, delimiter="\t", quotechar="^")
for i in ([len(i) for index, row in enumerate(reader)
if index == 0 for i in [row]]):
return column_setting(i)
def column_setting(column):
if column > 5:
text = ('Die ausgewählte Datei hat %s Spalten. \
\nWieviele Spalten sollen angezeigt werden?\n' % column)
column = state_value_setting(column, text)
if AUTOSETTINGS == 1:
return writeappend_txt(SETTING_FILE,
'HEADINGS = {}'.format([str(i) for i in range(column)]))
else:
print('\nVergeben Sie Ihre Spaltennamen!')
newcolumn = list()
newcolumn = ([(input('Eintrag zu: %s > ' % i))
for i in range(column)])
writeappend_txt(SETTING_FILE, 'HEADINGS = {}'.format(newcolumn))
return
def max_lines_per_segment_setting():
text = ('\nSpalten-Bennenungs-Zeile ab < %s > Datenzeilen. \
\nZum Ändern, geben Sie bitte einen neuen Zahlenwert ein!'
% MAX_LINES_PER_SEGMENT)
writeappend_txt(SETTING_FILE, 'MAX_LINES_PER_SEGMENT = {} \
'.format(state_value_setting(MAX_LINES_PER_SEGMENT, text)))
return
def listfilter_setting():
text = '\nSpezieller Filter für bessere Suchergebnisse.'
writeappend_txt(SETTING_FILE,
'LISTFILTER = {}'.format(state_setting(LISTFILTER, text)))
return
def case_sensitiv_setting():
text = '\nSuche mit: \
\n - Groß-/Kleinschreibung'
writeappend_txt(SETTING_FILE,
'CASE_SENSITIV = {}'.format(state_setting(CASE_SENSITIV, text)))
return
def auto_setting():
text = '\nAuto-Einstellung: \
\n - Auswahl der Datei \
\n - Automatische Übernahme der Spalten, \
\n bei Dateien mit nicht mehr als 5 Spalten'
writeappend_txt(SETTING_FILE,
'AUTOSETTINGS = {}'.format(state_setting(AUTOSETTINGS, text)))
return
def true_setting():
if input('\nEinstellungen übernehmen? \
\n< ja / [TASTE] für Abbruch > ') == 'ja':
print('\nUm die Einstellungen zu übernehmen, \
\nbeenden Sie das Menü und starten < %s > neu!\n'
% MODULNAME)
return os.remove(SETTING_COPY)
else:
print('\nDie Einstellungen wurden nicht verändert!')
return shutil.copy(SETTING_COPY, SETTING_FILE)
def base(menupoint):
copy_setting()
head()
filename_setting()
max_lines_per_segment_setting()
listfilter_setting()
case_sensitiv_setting()
auto_setting()
true_setting()
def auto(menupoint):
if AUTOSETTINGS == 1:
copy_setting()
head()
filename_setting()
writeappend_txt(SETTING_FILE,
'MAX_LINES_PER_SEGMENT = {} \
'.format(state_setting(MAX_LINES_PER_SEGMENT)))
writeappend_txt(SETTING_FILE,
'LISTFILTER = {}'.format(state_setting(LISTFILTER)))
writeappend_txt(SETTING_FILE,
'CASE_SENSITIV = {}'.format(state_setting(CASE_SENSITIV)))
writeappend_txt(SETTING_FILE,
'AUTOSETTINGS = {}'.format(state_setting(AUTOSETTINGS)))
true_setting()
def quit(menupoint):
print("\nMenü für Einstellungen wird beendet!\n")
exit()
def setting():
setting_menu(menu)
def setting_menu(menu):
while True:
print('\n<<< Menü für Einstellungen >>>')
for index, row in enumerate(menu, 1):
print("{} {}".format(index, row[0]))
try:
choice = int(input("Nummer: ")) - 1
menu[choice][1](menu[choice][2])
except (ValueError, IndexError):
print("\nBitte nur Zahlen im Bereich 1 - {} eingeben\n".
format(len(menu)))
menu = [
["Manuelle Einstellungen", base, 'manuell'],
["Automatik Einstellungen", auto, 'auto'],
["Beenden", quit, 'beenden']
]
if __name__ == "__main__":
setting_menu(menu)(int(sys.argv[1]))
#!/usr/bin/python3
# -*- coding: utf-8 -*-
FILENAME = "/pfad/zu/pythoninfo.txt"
HEADINGS = ['python2', 'python3', 'info']
MAX_LINES_PER_SEGMENT = 20
LISTFILTER = 1
CASE_SENSITIV = 0
AUTOSETTINGS = 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment