Code modülü ile python sürümü seçmek

arkadaşlar biz bir text editor yapıyoruz ama python sürümünü seçmeyi nasıl yapcağımı bilmiyorum

aslında merak ettiğim şey diğer text editorlerinin interpreter yolunu yazdıktan sonra nasıl oradan sonuçları alıyor

code modülünde InteractiveInterpreter in runcode fonksiyonundan output alıp değişkene nasıl koyarım

Aşağıdaki kodları inceleyin isterseniz. Python dosyası python3.8 ile çalışıyor. Menü’den yorumlayıcıyı seçiyorsunuz. Mesela yorumlayıcıyı /usr/bin/python3.6 olarak seçtim ben. Program python3.8 ile çalışmasına rağmen sol alandaki text widgetine girilen kodlar python3.6 ile yorumlanıyor. Bu arada çok fazla kontrol eklemedim. Maksat fikir vermek.

Kodlar:

#!/usr/bin/python3.8
# -*- coding: utf-8 -*-

import sys
import subprocess
import tkinter as tk

from tkinter.filedialog import askopenfilename


def command(interpreter: str, string: str):
    sys.stdout.write(
        subprocess.Popen(
            args=f"{interpreter} -c '{string}'",
            shell=True,
            stdout=subprocess.PIPE
        ).communicate()[0].decode("utf-8")
    )
    sys.stdout.flush()


class Text(tk.Text):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(side="left")


class Button(tk.Button):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(side="bottom")


class Frame(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack()


class Menu(tk.Menu):
    def __init__(
            self,
            run_button: Button,
            input_text: Text,
            output_text: Text,
            *args,
            **kwargs
    ):
        super().__init__(*args, **kwargs)
        self.master.configure(menu=self)
        self.add_command(label="Select Interpreter", command=self.select)
        self.run_button = run_button
        self.input_text = input_text
        self.output_text = output_text

    def select(self):
        try:
            selected = askopenfilename(filetypes=[("All Files", ".*")])
        except FileNotFoundError:
            selected = ""
        if selected:
            self.run_button["command"] = lambda: command(
                selected, self.input_text.get("1.0", "end")[:-1]
            )


class StdIOYonlendiricisi:
    def __init__(self, text: Text):
        self.text = text

    def write(self, string: str):
        self.text.delete("1.0", "end")
        self.text.insert("insert", string)

    def flush(self):
        self.text.update()


def main():
    root = tk.Tk()
    top_frame = Frame(master=root)
    bottom_frame = Frame(master=root)
    menu = Menu(
        master=root,
        run_button=Button(master=bottom_frame, text="Run"),
        input_text=Text(master=top_frame),
        output_text=Text(master=top_frame)
    )
    sys.stdout = StdIOYonlendiricisi(menu.output_text)
    root.mainloop()


if __name__ == "__main__":
    main()
1 Beğeni

Peki kodun uzunluğundan soruyorum bu işi hangi modül yapiyor

Şöyle anlatayım:

Tkinter’in filedialog modülü ile yorumlayıcıya ulaşıyoruz. Bulunan yorumlayıcı command fonksiyonunun interpreter parametresinin değeri oluyor. command fonksiyonunun string değeri de self.input_text widgetine yazılan yazılar oluyor. Run tuşuna bastığımız zaman, seçilmiş yorumlayıcı ile self.input_text widgetindeki karakter dizisi aşağıdaki fonksiyonun parametrelerinin değerleri haline geliyorlar ve fonksiyon bu parametrelerle çalışmaya başlıyor:

    sys.stdout.write(
        subprocess.Popen(
            args=f"{interpreter} -c '{string}'",
            shell=True,
            stdout=subprocess.PIPE
        ).communicate()[0].decode("utf-8")
    )
    sys.stdout.flush()

sys.stdout, output_txt'e yönlendirildiği için sonuç, sağ taraftaki text widgetine yazdırılıyor.

Biliyorsunuz, python kodlarını kabuk üzerinden çalıştırmak için şu komutu kullanıyoruz:

python3.8 -c 'print("hello")'

İşte, subprocess.Popen fonksiyonunun, args paramtresi de bu ifadeyi çalıştırıyor.

Haa pythonun yorumlayicisini komut dosyası ile cagirdigimizda bize sonucu dönüyor bizde o sonucu subprocress ile programımıza aliyoruz

subprocess.Popen ile çalıştırıyoruz. Popen sınıfının communicate metoduyla sonucu string olarak alıyoruz. Ve sonucu sys.stdout.write ile ekrana yazdırmaya çalışıyoruz. Ama sys.stdout, output_text widgetine yönlendirildiği için sonuç output_text widgetine yazdırılıyor.

1 Beğeni

Etkileşimli kabuk taklit edilmek isteniyorsa stdin ve stdout arayüze uygun şekilde yönlendirilip bu kullanılabilir. Burada da güzel bir örnek var.

@Emerald_Gamer modüllerle alakalı bize bir şey sormadan önce modülün ismini şuradaki sağ üst yere yazıp "Go"ya tıklarsanız daha ayrıntılı bilgi edinebilirsiniz.

1 Beğeni

şimdi de hata alırsa hatayı texte yükseltmiyor
ne yapmalıyım normalde hatayıda text widgetine göndermesi gerekmez mi?
birde nedense input yazınca donuyor
mesela input(">") yazınca

Sizce neden öyle oluyor hala anlamış değilim
Aynı kodlar sizdede öyle oluyor mu

Standart hata çıktısını widgete yönlendirmek için command fonksiyonunu aşağıdaki gibi değiştirin.

def command(interpreter: str, string: str):
    sys.stdout.write(
        subprocess.Popen(
            args=f"{interpreter} -c '{string}'",
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT
        ).communicate()[0].decode("utf-8")
    )
    sys.stdout.flush()

input için şuanlık yapabileceğim bir şey yok. Tkinter’ın bu iş için uygun olduğunu da söyleyemem. Belki de stdin'i taklit eden bir widget oluşturmak gerekiyordur.

1 Beğeni

Çok kolay değil ama mümkün, IDLE yapıyor mesela.

stdinde readline metodu var, bu metodu giriş yapılan arayüzde entere basıldığında içinde yazanları döndürecek hale getirebilirsin.

Bakmak lazım aslında. Üzerinde çalıştığım proje bitince, buna bir bakarım.

idle de tkinter ile yapılmış onda mesela print çalışıyor

peki yorumlayıcıyı anlık olarak almanın yolu yokmu mesela while döngüsüne aldığımızda bir şey olmuyor donuyor

Dostum paylaştığım kodlar fikir vermesi açısından paylaşıldı. Siz ayrıntıları hesaba katarak kendiniz bir uygulama yapmalısınız. O kodlarda değişmesi gereken yerler veya eklenmesi gereken şeyler illa vardır. Bunları tespit edip gereken iyileştirmeleri artık siz yapacaksınız.

son bir soru sorabilir miyim highlight ekledim de diğer dillerin syntaxlerini nasıl bulucam pythonunk kolay keyword modülü

Pygments’e bakabilirsin.

1 Beğeni