Skandináv Lottó Statisztika

 Az alábbi oldalakról:

Skandináv Lottó gyakoriság

Skandináv Lottó húzások

Négy statisztikai adatot szereztem meg.

  1. Leggyakrabban húzott számok.
  2. Legritkábban húzott számok.
  3. Leginkább várt számok.
  4. Legkevésbé várt számok.
Készítettem egy Python programot a feldolgozáshoz, ami:

  1. Elmenti az adatokat json fájlba.
  2. Készít egy nyomtatható PDF-t az adatokról.
  3. Az adatokat tisztítja, keveri és tetszőleges számú szelvényt állít elő, szintén nyomtatható PDF-be.
A fő ablak:


Egy felugró ablak a gyors szám bevitelhez.



Előkészületek:

Mappaszerkezet készítés tetszőleges helyen a Windowsban:




Segítség a PyCharm -hoz:
Megkeressük a mappa szerkezetünket és elkészítjük a virtuális környezetet itt:



A Python modulokat itt installáljuk, a PyCharm terminálban
pl: pip install numpy




Működés:
A statisztikai oldalról kinyert adatokat bevisszük és elmentjük.
Az adatmentés .json fájlba történik és az újabb mentések felülírják az előbbit.
Az utókornak el lehet menteni pdf-be, tetszőleges fájl név alá.

Az adatok további feldolgozásához, mint
- ismétlődő számok eltávolítása, 
- számok keverése, 
- szelvények készítése
használjuk az ablak jobb oldali funkcióit. 

Minden egyes "Lottó számok" gomb megnyomás más és más számokat generál az alap adatokból.

Egyéb: 
Win10 64bit, frissítve.
PyCharm 2024.1.5 (Community Edition)
Python 3.12.5 


A Kódok: 
Béta verzió!


alkalmazas.py
import tkinter as tk
from pprint import pprint
from tkinter import ttk
from tkinter import messagebox as ms
import numpy as np
import random
import json
import webbrowser
from tkinter import font

import pdfbeMent
import manager2 as mng

pprint('Layco')


class Window1(tk.Toplevel):
"""Felugró ablak az adatok, számok beviteléhez."""

def __init__(self, parent):
super().__init__(parent)

self.geometry('254x430+800+10')
self.title('Toplevel Window1')
self.configure(bg='#40B5AD')

self.szamok = []

self.frame1 = tk.Frame(self, relief=tk.RIDGE, bd=3, bg='#40B5AD')
self.frame1.grid(row=1, column=0, sticky=tk.E + tk.W + tk.N + tk.S, padx=30, pady=4)

self.frame2 = tk.Frame(self, relief=tk.RIDGE, bd=3, )
self.frame2.grid(row=2, column=0, sticky=tk.E + tk.W + tk.N + tk.S, padx=30, pady=4)

self.frame3 = tk.Frame(self, height=2, relief=tk.RIDGE, bd=3, )
self.frame3.grid(row=3, column=0, sticky=tk.E + tk.W + tk.N + tk.S, padx=30, pady=4)

self.frame4 = tk.Frame(self, relief=tk.RIDGE, bd=3, )
self.frame4.grid(row=4, column=0, sticky=tk.E + tk.W + tk.N + tk.S, padx=30, pady=4)

# Ez jeleníti meg azt az egy beütött számot
self.entry = tk.Entry(self.frame1, width=22,
font='Helvetica 11 bold',
bg="#CCCCFF")
self.entry.grid(row=0, column=0, padx=2, pady=2)

# metódus hívás
self.__gombok_szammal()

# A Toplevel bezárása gomb
tk.Button(self.frame4, text='Bezár',
font='Helvetica 11 bold',
width=19, bg='#088F8F',
command=self.destroy).grid(row=3, column=0, padx=2)

self.betutipus = font.Font(family="Helvetica", size=12, underline=True)

# Statisztikai adatok elérése.
self.url = 'https://www.lotto567.hu/skandinav_lotto/gyakorisag'

link = tk.Label(self, text="Lottó statisztikák.",
font=self.betutipus, bg='#40B5AD',
fg="blue",
cursor="hand2")
link.grid(row=5, column=0, padx=40, pady=20)

link.bind("<Button-1>", lambda e: self.open_url(self.url))

@staticmethod
def open_url(url):
webbrowser.open_new_tab(url)

def __gombok_szammal(self):
self.button_dict = {}
# 1-től 35-ig számlista készítés
m = np.arange(1, 36)
# lista készítés
szamlista = m.tolist()
# A szamlista index-ek
index = 0

for sor in range(7):
for oszlop in range(5):
def func(x=f'{szamlista[index]}'):
return self.entry_update(x)

self.button_dict[m[index]] = tk.Button(
self.frame2, font='Helvetica 11 bold', bg='#0047AB',
fg='#F0FFFF',
text=f'{szamlista[index]} ',
width=3,
anchor="e",
command=func)
self.button_dict[szamlista[index]].grid(row=sor, column=oszlop)

index += 1

def entry_update(self, text):
if len(self.szamok) < 7:
self.entry.delete(0, tk.END)
self.entry.insert(0, text)

# beütött számok gyűjtője
self.szamok.append(self.entry.get())

# A beütött összes, hét darab számot megjeleníti, folyamatosan
tk.Label(self.frame3,
text=self.entry.get() + ',', font='Helvetica 11').pack(side='left')

else:
ms.showinfo(title='Figyelem!', message=f'Beírtad a hét számot!\n'
f'{self.szamok}')


# Osztaly 1 ------------------------------------------------------------
class AdatBevitel(ttk.Frame):
"""Korábbi Skandináv lottó számok húzásaiból kinyert
statisztikai adatok, bevitele és mentése json fájlba.
Az ablak baloldali kerete, benne a widgetekkel."""

def __init__(self, container):
super().__init__(container)

# valtozók
self.osszes_adat = None
self.nemvart = None
self.vart = None
self.ritka = None
self.gyakori = None
self.husz4 = 24
self.husz5 = 25

# metódus
self.__widgetek1()

# Modul hívás
self.manager = mng.Manager2()

def __widgetek1(self):
paddings1 = {'padx': 5, 'pady': 5}
paddings2 = {'padx': 2, 'pady': 2}
ipaddings1 = {'ipadx': 0, 'ipady': 4}

# fentről lefele: frame 1
self.bkeret1 = ttk.Frame(self, style='bordo.TFrame')
self.bkeret1.grid(row=0, column=0, **paddings1)

# frame 2
self.bkeret2 = ttk.Frame(self, style='bordo.TFrame')
self.bkeret2.grid(row=1, column=0, rowspan=2, **paddings1)

# frame 3
self.bkeret3 = ttk.Frame(self, style='bordo.TFrame')
self.bkeret3.grid(row=3, column=0, rowspan=2, **paddings1)

# frame 4
self.bkeret4 = ttk.Frame(self, style='bordo.TFrame')
self.bkeret4.grid(row=5, column=0, rowspan=2, **paddings1)

# frame 5
self.bkeret5 = ttk.Frame(self, style='bordo.TFrame')
self.bkeret5.grid(row=7, column=0, rowspan=2, **paddings1)

# frame 6
self.bkeret6 = ttk.Frame(self, style='bordo.TFrame')
self.bkeret6.grid(row=9, column=0, rowspan=2, **paddings1)

# --------------------------------------------------------

# fentről lefele: button 1 toplevelt nyit.
szambe_gomb = ttk.Button(self.bkeret1,
text='Számok bevitele',
width=self.husz4,
command=self.__open_window)
szambe_gomb.pack(side=tk.TOP, **paddings2)

# ---------------------------------------------------------

# button 2
self.gyakoributton = ttk.Button(self.bkeret2, style='mentes.TButton',
text='Leggyakoribb számok',
width=self.husz4,
state=tk.NORMAL,
command=self.gyakori_fuggveny)
self.gyakoributton.pack(side=tk.TOP, **paddings2)

# fentről lefele: Label 1
self.gyakorilabel = ttk.Label(self.bkeret2,
text='Adat',
width=self.husz5,
anchor=tk.CENTER)
self.gyakorilabel.pack(side=tk.TOP, **paddings2, **ipaddings1)

# ----------------------------------------------------------------

# button 3
self.ritkabutton = ttk.Button(self.bkeret3, style='mentes.TButton',
text='Legritkább számok',
width=self.husz4,
state=tk.NORMAL,
command=self.ritka_fuggveny)
self.ritkabutton.pack(side=tk.TOP, **paddings2)

# Label 2
self.ritkalabel = ttk.Label(self.bkeret3,
text='Adat',
width=self.husz5,
anchor=tk.CENTER)
self.ritkalabel.pack(side=tk.TOP, **paddings2, **ipaddings1)

# --------------------------------------------------------------

# Button 4
self.vartbutton = ttk.Button(self.bkeret4, style='mentes.TButton',
text='Leginkább várt számok',
width=self.husz4,
state=tk.NORMAL,
command=self.vart_fuggveny)
self.vartbutton.pack(side=tk.TOP, **paddings2)

# Label 3
self.vartlabel = ttk.Label(self.bkeret4,
text='Adat',
width=self.husz5,
anchor=tk.CENTER
)
self.vartlabel.pack(side=tk.TOP, **paddings2, **ipaddings1)

# -------------------------------------------------------------

# Button 5
self.nemvartbutton = ttk.Button(self.bkeret5, style='mentes.TButton',
text='Legkevésbé várt számok',
width=self.husz4,
state=tk.NORMAL,
command=self.nemvart_fuggveny)
self.nemvartbutton.pack(side=tk.TOP, **paddings2)

# Label 4
self.nemvartlabel = ttk.Label(self.bkeret5,
text='Adat',
width=self.husz5,
anchor=tk.CENTER
)
self.nemvartlabel.pack(side=tk.TOP, **paddings2, **ipaddings1)

# button 6
self.mentesbutton = ttk.Button(self.bkeret6, text='Adatok mentése',
width=self.husz4,
state=tk.NORMAL,
command=self.adatok_irasa_fajlba)
self.mentesbutton.pack(side=tk.TOP, **paddings2)

# toplevel nyitás --------------------------------------------------
def __open_window(self):
self.window1 = Window1(self)
self.window1.grab_set()

# -------------------------------------------------------------------

def gyakori_fuggveny(self):
try:
self.gyakori = self.window1.szamok

except AttributeError:
ms.showerror(title='Figyelem!', message=f'Hoppá! - nincs adat.')

else:
# print(f'{self.gyakori=}, {type(self.gyakori)}')
# A gyakorilabel megjelenítő részére átkonfigurálva
labelbe1 = [int(i) for i in self.gyakori]
self.gyakorilabel.configure(text=f'{labelbe1}')

def ritka_fuggveny(self):
self.ritka = self.window1.szamok
# A gyakorilabel megjelenítő részére átkonfigurálva
labelbe2 = [int(i) for i in self.ritka]
self.ritkalabel.configure(text=f'{labelbe2}')

def vart_fuggveny(self):
self.vart = self.window1.szamok
# A gyakorilabel megjelenítő részére átkonfigurálva
labelbe3 = [int(i) for i in self.vart]
self.vartlabel.configure(text=f'{labelbe3}')

def nemvart_fuggveny(self):
self.nemvart = self.window1.szamok
# A gyakorilabel megjelenítő részére átkonfigurálva
labelbe4 = [int(i) for i in self.nemvart]
self.nemvartlabel.configure(text=f'{labelbe4}')

def adatok_irasa_fajlba(self):
"""A négy bevitt adatot (gyakori, ritka, várt, nemvárt)
elmenti egy json fájlba, kétjegyu_stringszam_keszítes()
metódus hívással."""
try:
adatok = self.gyakori + self.ritka + self.vart + self.nemvart

# A manager2 modul statikus függvénye
self.osszes_adat = self.manager.ketjegyu_stringszam_keszites(adatok)
print(self.osszes_adat)

except TypeError:
ms.showerror(title='Híba', message='Még nem volt adatbevitel!\n'
'Próbálkozz a beolvasással!')

else:
print('Minden oké!')

# szótárba rendezés
dictionary = {
"name": self.osszes_adat}
json_object = json.dumps(dictionary)

# adatok írása fájlba
with open("jsonfajlok/mentes1.json", "w", encoding='utf_8') as outfile:
outfile.write(json_object)


# Osztály 2 -------------------------------------------------------------------
class AdatLekeres(ttk.Frame):
"""A beolvasott adatok mentése PDF-be
Az ablak középső Frame oszlopa."""

def __init__(self, container):
super().__init__(container)
self.husz3 = 23
self.husz4 = 24
self.husz5 = 25
self.lekert_adatok = None

# metódus hívás
self.__widgetek2()

# manager2 modul hívás
self.manager = mng.Manager2()

def __widgetek2(self):
paddings1 = {'padx': 5, 'pady': 5}
paddings2 = {'padx': 2, 'pady': 2}
ipaddings1 = {'ipadx': 0, 'ipady': 4}

# frame 1
self.kkeret1 = ttk.Frame(self, style='szurke.TFrame',
)
self.kkeret1.grid(row=0, column=0, rowspan=2,
**paddings1)

# frame 2
self.kkeret2 = ttk.Frame(self, style='szurke.TFrame',
)
self.kkeret2.grid(row=2, column=0, rowspan=2,
**paddings1)

# frame 3
self.kkeret3 = ttk.Frame(self, style='szurke.TFrame',
)
self.kkeret3.grid(row=4, column=0, rowspan=2,
**paddings1)

# középső oszlop vidgetei ---------------------------------------------------
# label 1
label1 = ttk.Label(self.kkeret1,
style='hatter.TLabel',
text='Adat feldolgozas',
width=self.husz5,
anchor=tk.CENTER)
label1.pack(side=tk.TOP, **paddings2, **ipaddings1)

# button 1
adat_olvas_gomb = ttk.Button(self.kkeret1,
style='kozep.TButton',
text='Adatok beolvasása',
width=self.husz4,
command=self.adatok_beolvasasa)
adat_olvas_gomb.pack(side=tk.TOP, **paddings2)

# Text 1
self.adatok_text = tk.Text(self.kkeret2,
font=('Light Condensed', 11),
bg='#7DF9FF',
width=self.husz5,
height=4)
self.adatok_text.pack(side=tk.TOP,
**paddings2)

# pdf mentés -------------------------------------------------------------

# button 2
szelveny_ment_gomb = ttk.Button(
self.kkeret3,
style='kozep.TButton',
text='Adatok PDF-be',
width=self.husz4,
command=self.szamok_mentese)
szelveny_ment_gomb.pack(side=tk.TOP, **paddings2)

# label 2
self.fajlnev_kero_label = ttk.Label(
self.kkeret3,
style='hatter.TLabel',
text='Kérem a pdf nevét!',
width=self.husz5,
anchor=tk.CENTER)

self.fajlnev_kero_label.pack(side=tk.TOP,
**paddings2, **ipaddings1)

# entry
self.fajlnev_entry = tk.Entry(self.kkeret3,
font='Helvetica 11 bold',
width=20, bg='#F0E68C', bd=3)
self.fajlnev_entry.pack(side=tk.TOP, padx=6, pady=(2, 8))
self.fajlnev_entry.focus()

# label 3
self.szelveny_ment_label = ttk.Label(
self.kkeret3,
style='hatter.TLabel',
text='Mentésre vár',
width=self.husz5,
anchor=tk.CENTER)

self.szelveny_ment_label.pack(side=tk.TOP,
**paddings2, **ipaddings1)

# ---------------------------------------------------------------------------

def adatok_beolvasasa(self):
"""Az elmentett számokat a négy bevitt adattal
(gyakori, ritka, várt, nemvárt) beolvassa listába.
Szeleteléssel négy egyenlő részre osztja és megjeleníti
a Text-ben."""
f = open('jsonfajlok/mentes1.json')

# adatok betöltése
data = json.load(f)

# Az elmentett adatok kinyerése listába.
self.lekert_adatok = data['name']
# fájl lezárás
f.close()

try:
# print(self.lekert_adatok)
szelet1 = self.lekert_adatok[0:7]
szelet2 = self.lekert_adatok[7:14]
szelet3 = self.lekert_adatok[14:21]
szelet4 = self.lekert_adatok[21:]

except TypeError:
ms.showerror(title='Híba',
message='Még nem volt adatbevitel!')

else:
# A text szövegmező tisztára törlése
self.adatok_text.delete("1.0", "end")

# új adatok bevitele
for i1 in range(6, -1, -1):
self.adatok_text.insert('1.0',
f'{szelet1[i1]}, ')

for i2 in range(6, -1, -1):
if i2 == 6:
self.adatok_text.insert('2.0',
f'\n{szelet2[i2]}, ')
else:
self.adatok_text.insert('2.0',
f'{szelet2[i2]}, ')

for i3 in range(6, -1, -1):
if i3 == 6:
self.adatok_text.insert('3.0',
f'\n{szelet3[i3]}, ')
else:
self.adatok_text.insert('3.0',
f'{szelet3[i3]}, ')

for i4 in range(6, -1, -1):
if i4 == 6:
self.adatok_text.insert('4.0',
f'\n{szelet4[i4]}, ')
else:
self.adatok_text.insert('4.0',
f'{szelet4[i4]}, ')

def adatok_mentese_pdfbe(self):
"""elmenti az adatokat PDF -be!"""

try:
szelet1 = self.lekert_adatok[0:7]
szelet2 = self.lekert_adatok[7:14]
szelet3 = self.lekert_adatok[14:21]
szelet4 = self.lekert_adatok[21:]

except TypeError:
ms.showerror(title='Híba!',
message='Nyomd meg az "Adatok_beolvasása" gombot!')

else:
pdfbeMent.PdfMentes(szelet1,
szelet2,
szelet3,
szelet4,
self.fajlnev_entry.get())

self.szelveny_ment_label.configure(text='MENTVE!')

def szamok_mentese(self):
"""Elmenti az adatokat pdf-be.
Két metódus hívást végez: self.darab_ellenor és
self.adatok_mentése_pdfbe
"""
fajl_nev = self.fajlnev_entry.get()
# metódus hívás
if not self.manager.darab_ellenor(fajl_nev):
ms.showerror(title='Híba!',
message='A fájl neve 10db karakterből lehet!')
else:
# metódus hívás
self.adatok_mentese_pdfbe()


class AdatVarialas(ttk.Frame):
"""A meghívott adatokból lottószámok készítése
és mentése PDF-be. Jobb oldali Frame."""

def __init__(self, container):
super().__init__(container)

self.beolvasott_adatok = None
self.uj_lista = None
self.husz3 = 23
self.husz4 = 24
self.husz5 = 25

# widgetek betöltése, metódus hívás
self.__widgetek3()

# manager2 modul hívás
self.manager = mng.Manager2()

def __widgetek3(self):
"""A jobb oldali frame widgetei."""
paddings1 = {'padx': 5, 'pady': 5}
paddings2 = {'padx': 2, 'pady': 2}
ipaddings1 = {'ipadx': 0, 'ipady': 4}

# frame 1
self.jkeret1 = ttk.Frame(self, style='szurke.TFrame',
)
self.jkeret1.grid(row=0, column=0, rowspan=2,
**paddings1)

# frame 2
self.jkeret2 = ttk.Frame(self, style='szurke.TFrame',
)
self.jkeret2.grid(row=2, column=0, rowspan=2,
**paddings1)

# frame 3
self.jkeret3 = ttk.Frame(self, style='szurke.TFrame',
)
self.jkeret3.grid(row=4, column=0, rowspan=2,
**paddings1)

# label 1
label1 = ttk.Label(self.jkeret1,
style='hatter.TLabel',
text='SkandiLottók',
width=self.husz5,
anchor=tk.CENTER)
label1.pack(side=tk.TOP, **paddings2, **ipaddings1)

# button 1
adat_olvas_gomb = ttk.Button(self.jkeret1,
style='kozep.TButton',
text='Lottó számok',
width=self.husz4,
command=self.adat_beolvasas)
adat_olvas_gomb.pack(side=tk.TOP, **paddings2)

# Text 1
self.lotto_text = tk.Text(self.jkeret2,
font=('Light Condensed', 11),
bg='#7DF9FF',
width=self.husz5,
height=4)
self.lotto_text.pack(side=tk.TOP, **paddings2)

# mentés pdf -be -----------------------------------------------------

# button 2
szelveny_ment_gomb = ttk.Button(self.jkeret3,
style='kozep.TButton',
text='Lottók PDF-be',
width=self.husz4,
command=self.szamok_mentese)
szelveny_ment_gomb.pack(side=tk.TOP, **paddings2)

# label 2
self.fajlnev_kero_label = ttk.Label(self.jkeret3,
style='hatter.TLabel',
text='Kérem a pdf nevét!',
width=self.husz5,
anchor=tk.CENTER)

self.fajlnev_kero_label.pack(side=tk.TOP,
**paddings2, **ipaddings1)

# entry
self.pdfnev_entry = tk.Entry(self.jkeret3,
font='Helvetica 11 bold',
width=20, bg='#F0E68C', bd=3)
self.pdfnev_entry.pack(side=tk.TOP, padx=6, pady=(2, 8))
self.pdfnev_entry.focus()

# label 3
self.szelveny_ment_label = ttk.Label(
self.jkeret3,
style='hatter.TLabel',
text='Mentésre vár',
width=self.husz5,
anchor=tk.CENTER)

self.szelveny_ment_label.pack(side=tk.TOP,
**paddings2, **ipaddings1)

# ---------------------------------------------------------------------------

def adat_beolvasas(self):
"""Az elmentett adat szótárt a négy bevitt statisztikai
adattal (gyakori, ritka, várt, nemvárt) megnyitja """
f = open('jsonfajlok/mentes1.json')

# adatok betöltése
data = json.load(f)
# lista kinyerése
self.beolvasott_adatok = data['name']
# fájl lezárás
f.close()

try:
# Az ismétlődő számok törlése a set() metódussal,
# és ezzel egy lépésben "számkeveredés".
uj_halmaz = set(self.beolvasott_adatok)
# print(f'{uj_halmaz=}')

# A maradék halmazból lista készítés.
self.uj_lista = list(uj_halmaz)
# A lista elem darabszáma
# print(f'{len(uj_lista)}db')

# lottószámokhoz kevert lista készítés
random.shuffle(self.uj_lista)
print(f'Kevert lista:\n{self.uj_lista=}\n{len(self.uj_lista)}db')

# Ha nincs meg a json fájl az adatokkal
except TypeError:
ms.showerror(title='Hiba',
message='Még nem volt adatbevitel!')

else:
# metódus hívás
self.lotto_szamok_textben()

def lotto_szamok_textben(self):
"""A self.uj_lista -ból Lottószám sorozatok készítése
szeleteléssel és megjelenítése a Text-ben.
"""
szelet1 = self.uj_lista[0:7]
# print(len(szelet1))
szelet2 = self.uj_lista[7:14]
szelet3 = self.uj_lista[14:21]
szelet4 = self.uj_lista[21:]
# print(len(szelet4))

# A szövegmező tisztára törlése
self.lotto_text.delete("1.0", "end")
# új adatok bevitele
for i in range(6, -1, -1):
self.lotto_text.insert('1.0',
f'{szelet1[i]}, ')

for i in range(6, -1, -1):
if i == 6:
self.lotto_text.insert('2.0',
f'\n{szelet2[i]}, ')
else:
self.lotto_text.insert('2.0',
f'{szelet2[i]}, ')

for i in range(6, -1, -1):
if i == 6:
self.lotto_text.insert('3.0',
f'\n{szelet3[i]}, ')
else:
self.lotto_text.insert('3.0',
f'{szelet3[i]}, ')

# Esetleges adatszámok ismétlődese estén,
# az azonos számok törlése miatt, nincs 4x7 szám!
szam = len(szelet4) - 1
for i in range(szam, -1, -1):
if i == szam:
self.lotto_text.insert('4.0',
f'\n{szelet4[i]}, ')
else:
self.lotto_text.insert('4.0',
f'{szelet4[i]}, ')

def adatok_mentese_pdfbe(self):
"""elmenti az adatokat PDF -be!"""

try:
szelet1 = self.uj_lista[0:7]
szelet2 = self.uj_lista[7:14]
szelet3 = self.uj_lista[14:21]
szelet4 = self.uj_lista[21:]

except TypeError:
ms.showerror(title='Híba!',
message='Nyomd meg a "Lottó számok" gombot!')

else:
pdfbeMent.PdfMentes(szelet1,
szelet2,
szelet3,
szelet4,
self.pdfnev_entry.get())

self.szelveny_ment_label.configure(text='MENTVE!')

def szamok_mentese(self):
"""Elmenti a lottószámokat pdf-be.
Két metódus hívást végez: self.darab_ellenor és
self.szelvenyek_mentése_pdfbe"""
fajl_nev = self.pdfnev_entry.get()

# modul statikus metódus hívás
if not self.manager.darab_ellenor(fajl_nev):
ms.showerror(title='Híba!',
message='A fájl neve 10db karakterből lehet!')
else:
# metódus hívás
self.adatok_mentese_pdfbe()


class App(tk.Tk):
"""Grafikus ablak három frame osztállyal."""

def __init__(self):
super().__init__()
self.title('Skandináv Lottó')
self.configure(bg='#F0E68C')

paddings3 = {'padx': (3, 1), 'pady': 3}
paddings4 = {'padx': (1, 1), 'pady': 3}
paddings5 = {'padx': (1, 3), 'pady': 3}

# configure style -------------------------------------------------------
self.stylus = ttk.Style(self)
self.stylus.theme_use('alt')

# Ez a frame osztály fő sílusa ---------------------------------------------
self.stylus.configure('TFrame',
relief=tk.RIDGE,
bd=3)

# A frame osztály al 1. stílusa.------------------------------------------
self.stylus.configure('bordo.TFrame', )

# frame 1 stílus map
self.stylus.map('bordo.TFrame',
background=[('!disabled', '#900C3F')])

# A frame osztály al 2. stílusa -------------------------------------------
self.stylus.configure('szurke.TFrame', )

# frame 2 stílus map
self.stylus.map('szurke.TFrame',
background=[('!disabled', '#36454F')])

# A fő label stílus------------------------------------------------------------------------
# konfigurálás
self.stylus.configure('TLabel',
font=('Helvetica', 11, 'bold'),
relief=tk.RIDGE,
bd=3)
# Fő label stílus map, háttérszín beállítás
self.stylus.map('TLabel',
background=[('!disabled', '#088F8F')])

# Al label stílus map(), háttérszin változtatás
self.stylus.map('hatter.TLabel',
background=[('!disabled', '#00FFFF')])

# ----------------------------------------------------------------------------
# Fő button stílus konfigurálás -----------------------------------------------
self.stylus.configure('TButton',
font=('Helvetica', 11, 'bold'),
relief=tk.RAISED,
bd=3)

# Fő button stílus map() szinek megadása
self.stylus.map('TButton',
foreground=[('!disabled', '#EDEADE')],
background=[('!disabled', '#0F52BA'),
('disabled', '#C2B280')])

# Al button stílus map() 1.
self.stylus.map('mentes.TButton',
foreground=[('!disabled', '#EDEADE')],
background=[('!disabled', '#088F8F'),
('disabled', '#C2B280')])

# Al button stílus map() 2.
self.stylus.map('kozep.TButton',
background=[('!disabled', '#0047AB')])

# Osztály példány 1 ------------------------------------------------------
self.adatbevitel = AdatBevitel(self)
self.adatbevitel.pack(fill=tk.BOTH, expand=True, side=tk.LEFT,
**paddings3)
self.adatbevitel.configure(style='bordo.TFrame')

# Osztály példány 2 -------------------------------------------------------
self.adatlekeres = AdatLekeres(self)
self.adatlekeres.pack(fill=tk.BOTH, expand=True, side=tk.LEFT,
**paddings4)
self.adatlekeres.configure(style='szurke.TFrame')

# Osztály példány 3
self.adatvarialas = AdatVarialas(self)
self.adatvarialas.pack(fill=tk.BOTH, expand=True, side=tk.LEFT,
**paddings5)
self.adatvarialas.configure(style='szurke.TFrame')


if __name__ == "__main__":
app = App()
app.mainloop()




manager2.py

class Manager2:

@staticmethod
def ketjegyu_stringszam_keszites(str_szamlista):
"""Az egyjegyű 1, 2, 3, stb számokból kétjegyű string
'01', '02', '03', '04', stb számot készít."""
uj_lista = []
for szam in str_szamlista:
if int(szam) < 10:
ujszam = f'{szam.zfill(2)}'
uj_lista.append(ujszam)
else:
uj_lista.append(szam)

return uj_lista

@staticmethod
def darab_ellenor(adat):
"""Ellenőrzi, hogy van e név megadva és
névnek a hosszát."""
if len(adat) < 10 and adat.strip():
return True
return False

Itt is elérhető:



pdfbeMent.py
# https://ioflood.com/blog/python-get-current-date/
# https://docs.reportlab.com/reportlab/userguide/ch1_intro/
# https://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/
# pip install reportlab

from reportlab.pdfgen import canvas as ca
from reportlab.lib.pagesizes import A4
from datetime import date


class PdfMentes(ca.Canvas):
def __init__(self, sz1, sz2, sz3, sz4, fajlneve):
super().__init__("pdffajlok/" + fajlneve + ".pdf", pagesize=A4)

# A mai dátum beszerzése
self.mai_datum = date.today()

self.sz1 = sz1
self.sz2 = sz2
self.sz3 = sz3
self.sz4 = sz4

self.width, self.height = A4

# a setFillColoRGB()metódus beállítja a lapra rajzolt
# bármely objektum kitöltési színét és a betűk színét.
# A PDF alkalmazás (sumatra) háttérszínétől függő!
self.setFillColorRGB(0.0, 0.0, 1.0)

# létre kell hozni a megfelelő objektumot,
# jelezve, hogy hova szeretnénk helyezni a szöveget
self.text = self.beginText(50, self.height - 50)

# itt is van egy setFont()metódus, de ez az adott objektumra hat,
# és nem a lap többi részére.
self.text.setFont("Times-Roman", 20)

# A textLine() metódus segítségével szövegsorokat adunk az objektumunkhoz.
self.text.textLines(f'{fajlneve}'
f'\nKészült: {self.mai_datum}'
f'\n')
self.text.textLine(f'{self.sz1}')
self.text.textLine(f'{self.sz2}')
self.text.textLine(f'{self.sz3}')
self.text.textLine(f'{self.sz4}')

# Miután megírtuk a szöveget, felrajzoljuk a lapra.
self.drawText(self.text)

# befejeztük a munkát az aktuális lapon
self.showPage()

self.save()


if __name__ == '__main__':
pdf = PdfMentes(1, 2, 3, 4, 'layco3')


Itt is elérhető:



Kártya játékban létrehozott objektumok és attribútumok, törlése.

 Kicsit tömény lesz a példa, de nagyon fontos. Igyekeztem ellátni magyarázatokkal.

https://drive.google.com/file/d/18lRM6WeiDn1Al74aGQG4NQzJGUJlL5X8/view?usp=sharing

import tkinter as tk
from PIL import Image, ImageTk


# from pprint import pprint


class ButtonBind(tk.Tk):
def __init__(self):
super().__init__()

self.geometry('500x400+500+100')

self.img = {}
self.button = {}

self.frame = tk.Frame(self)
self.frame.pack()

self.fajl_lista = ["10_kör.png",
"02_káró.png",
"08_pikk.png"]

for i in range(0, 3):
self.img_file = Image.open(f"fkartyak/{self.fajl_lista[i]}")
self.img[i] = ImageTk.PhotoImage(self.img_file)

# A Button widgetek kép attribútumai: típus, sztring név.
print('\n', self.img[i]) # pyimage1, pyimage2, pyimage3
print(type(self.img[i])) # <class 'PIL.ImageTk.PhotoImage'> .....
print(f'sztring: {str(self.img[i])}')

self.button[i] = tk.Button(self.frame, image=str(self.img[i]))
self.button[i].pack(side='left')
self.button[i].bind('<Button-1>', self.main)

def main(self, event):
if event.widget.cget('image') == 'pyimage1':
print(f'\n{self.fajl_lista[0]}')
print(f'{int(self.fajl_lista[0][0:2])}')
self.button[0].destroy()

elif event.widget.cget('image') == 'pyimage2':
print(f'\n{self.fajl_lista[1]}')
print(f'{int(self.fajl_lista[1][0:2])}')
self.button[1].destroy()

elif event.widget.cget('image') == 'pyimage3':
harmadik_kepfajl = self.fajl_lista[2]
print(f'\n Harmadik_kepfajl: {harmadik_kepfajl}')

harmadik_kepfajl_ertek = int(self.fajl_lista[2][0:2])
print(f'harmadik_kepfajl_ertek: {harmadik_kepfajl_ertek}')

# kép törlése a gombbal együtt
self.button[2].destroy()

# ********************************************************************

# Kép fájl objektum attributumának a megjelenítése
print(f'\nself.img_file: {self.img_file}')
# self.img_file: <PIL.PngImagePlugin.PngImageFile image mode=RGB size=102x138 at 0x28F9E11BB00>

# Az attribútum törlése
del self.img_file

try:
print(f'self.img_file: {self.img_file}')

except AttributeError:
print('A "_tkinter.tkapp" objektumnak nincs "img_file" attribútuma,\n'
'mert törölve lett!')

else:
print('Minden okés!')

# **************************************************************************

# A kép objektumok és a memória helyük kiíratása
print(f'\nself.img: {self.img}')
# self.img: {0: <PIL.ImageTk.PhotoImage object at 0x0000028F9C0CBFB0>,
# 1: <PIL.ImageTk.PhotoImage object at 0x0000028F9E08C980>,
# 2: <PIL.ImageTk.PhotoImage object at 0x0000028F9E11BA10>}

# A harmadik azaz a kettes indexű kártyalap objektumának a törlése
del self.img[2]
# Újra kiírat
print(f'self.img: {self.img}')
# self.img: {0: <PIL.ImageTk.PhotoImage object at 0x000001ED666B8AA0>,
# 1: <PIL.ImageTk.PhotoImage object at 0x000001ED666B8A40>}
# A 2 indexű kép objektum törölve!

# ******************************************************************************

# A Button objektumok megjelenítése
print(f'\nself.button: {self.button}')
# self.button: {0: <tkinter.Button object .!frame.!button>,
# 1: <tkinter.Button object .!frame.!button2>,
# 2: <tkinter.Button object .!frame.!button3>}

# A hármas azaz a kettes indexű (kép) Button törlése a szótárból.
del self.button[2]
print(f'self.button: {self.button}')
# self.button: {0: <tkinter.Button object .!frame.!button>,
# 1: <tkinter.Button object .!frame.!button2>}
# A 2 indexű Button objektum törölve!


if __name__ == '__main__':
ablak = ButtonBind()
ablak.mainloop()

További tananyag: https://realpython.com/python-del-statement/


Kártya játék Francia kártyával.

 A YouTube -on láttam egy kártyajáték videó kódot és mivel nem értettem, gondoltam csinálok én is egyet. Tovább fejleszthető.

import random
import tkinter as tk
from tkinter import messagebox


class PakliKeszites:
def __init__(self):

self.pakli = []

def pakli_keszites(self):
szinek = ['pikk', 'treff', 'kör', 'káró']

for szin in szinek:
for ertek in range(2, 15):
if ertek < 10:
self.pakli.append(f'0{ertek}_{szin}.png')
else:
self.pakli.append(f'{ertek}_{szin}.png')

random.shuffle(self.pakli)

return self.pakli


class Main(tk.Tk):
def __init__(self):
super().__init__()

self.title('Kártya játék.')
self.geometry('500x400+800+100')
self.configure(bg='green')

self.jatekos_pont = 0
self.oszto_pont = 0

# Keret a két kártyalapnak
self.frame = tk.Frame(self, bg='green')
self.frame.pack(pady=20)

self.jatekos_frame = tk.LabelFrame(self.frame,
text='Játékos',
bg='yellow')
self.jatekos_frame.grid(row=0, column=0, padx=20,
pady=20, ipadx=10, ipady=5)

self.oszto_frame = tk.LabelFrame(self.frame,
text='Osztó',
bg='yellow')
self.oszto_frame.grid(row=0, column=1, padx=20,
pady=20, ipadx=10, ipady=5)

self.jatekos_label = tk.Label(self.jatekos_frame, image='')
self.jatekos_label.pack()

self.oszto_label = tk.Label(self.oszto_frame, image='')
self.oszto_label.pack()

self.ujlapok = tk.Button(self, text='Osztás',
command=self._uj_osztas)
self.ujlapok.pack(pady=20)

keszito = PakliKeszites()
self.pakli = keszito.pakli_keszites()

self._kezdo_osztas()

def _kezdo_osztas(self):
self.jatekos_lap = self.pakli.pop()
self.oszto_lap = self.pakli.pop()

self.jatekos_photo = tk.PhotoImage(
file=f"images2/{self.jatekos_lap}")
self.oszto_photo = tk.PhotoImage(
file=f"images2/{self.oszto_lap}")

self.jatekos_label.config(image=self.jatekos_photo)
self.oszto_label.config(image=self.oszto_photo)

self.title(f'Lapok száma: {len(self.pakli)}')

self.eredmeny_jelzo()

def _uj_osztas(self):
del self.jatekos_lap
del self.oszto_lap
del self.jatekos_photo
del self.oszto_photo

try:
self.jatekos_lap = self.pakli.pop()
self.oszto_lap = self.pakli.pop()

self.title(f'Lapok száma: {len(self.pakli)}')

except IndexError:
self.title(f'A lapok elfogytak!: {len(self.pakli)}')

valasz = tk.messagebox.askquestion(
title='Vége a partinak!',
message='Új játék mehet?') # no, yes

if valasz == 'no':
self.destroy()
else:
self.destroy()
Main()

else:
self.jatekos_photo = tk.PhotoImage(
file=f"images2/{self.jatekos_lap}")
self.oszto_photo = tk.PhotoImage(
file=f"images2/{self.oszto_lap}")

self.jatekos_label.config(image=self.jatekos_photo)
self.oszto_label.config(image=self.oszto_photo)

self.eredmeny_jelzo()

def eredmeny_jelzo(self):
self.jatekos_pont += int(self.jatekos_lap[:2])
self.oszto_pont += int(self.oszto_lap[:2])
print(f'Játékos pontjai: {self.jatekos_pont}')
print(f'Osztó pontjai: {self.oszto_pont}')


if __name__ == '__main__':
m = Main()
m.mainloop()

A kártya képek fájl nevei:

02_káró.png

02_kör.png

02_pikk.png

02_treff.png

stb..stb..

14_káró.png

14_kör.png

14_pikk.png

14_treff.png


Layco


Válaszok, válaszolók

Különböző fórumokon a programozással kapcsolatos kérdésekre elsősorban a Moderátorok válaszolnak. A kérdezők felé fontos igényeket fogalmaz meg a csoport szabályzata. Kevesebb elvárással találkozom a válaszolók felé. Ezzel kapcsolatban szeretnék néhány gondolatot megosztani. Egyszerűen azért mert több helytelen, használhatatlan válasszal találkoztam már. A jó válasz kritériumai:

  • A kérdésre válaszol.
  • Nem személyeskedik.
  • Egyszerűen fogalmaz lényegre törő válaszokat ad.
  • A teljes javított működő kódot prezentálja.
  • Építő jellegű kérdéseket tesz fel, ha nem ért valamit.
  • Nem kioktató.
  • Nincsenek előítéletei.
  • Nyugodt, kedves, barátságos, segítőkész. 
  • Szívesen válaszol, vagy sehogy.



Kép Pixabay