# input(data) -->   information  --> knowledge 
# CS = problem solving  (algorithm) unamb.
# SDLC --> waterfull (huge deliver. + long time)
# syntax - runtime - logical errors
# Display <--    display >--
# test suite (inputs & expected outputs   1    4)   testing
# 
'''
x = 50
x = "asd" #valid 

print(id(x)) #address 

print(type(x)) #datatype
'''
#priority    associtvie  2 + 3 - 4

# if loop(for while)
'''
if 1+2 == 5:
    print("ok")
else:
    print("no")

#ternary operator
print(1+2) if 'a'.isdigit() else print(1-2)


x = int(  input("Enter number of student") ) + 10 #string
print(x)


# for loop on seq.[string list disctionary tuple]
range(5) #[0, 1, 2, 3, 4]
range(1, 5, 1) #[1, 2, 3, 4]
range(5, 1, -1) #[5, 4, 3, 2]
range(float('asd')) #invalid

for i in range(5, 1, -1):
    print(i)


name = "hamada"
i = "x"
#print(i in name)
for i in name:
    print(i)


name = ["a", "b"]  #[a, b, A, B, A, B, A, B, A, B .......]
for i in name:
    i.upper()
print(name)

l = [24, "a", True]
for i in l:
    print(i.upper())


print([1, 2, 3]   * 1)


l = [3, [4, [5, 9], 1], 8]

print(l[1])

#dictionary key:value

d = { 3:"val1" , 2:6  }

#print(d["x"])

#for i in d.values():
#    print(i)

print(sorted(d.keys()))


d = { 3:"val1" , 2: {"s":"ss", "v":"bb" }  }

print(d[2]["v"])


def myfunc(a, b):
    z = a + b
    print(z)
    return a, b, z #tuple

x = myfunc(2, 3)
print(   type(x)  )


#global local var. 

def test():
    global x
    x = 2
    return x + 1

x = 5
print(test())

print("x after function", x)

def test(a, b = 3):
    print(a, b)

test(2)
test(2, 4)


def test(name):
    x = [3, 5, 1]
    print(  name(x)  )

print(  test(sorted)   )


def test(*numbers): #numbers [2, 3 ]
    res = 0
    for i in numbers:
        res += i
    return res

print( test(2, 3, 6, 5,4, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9)  )


z = lambda x, y: x + y

print(z(1, 2))

# modules X محذوف
# recusive function X
#OOP

class test: #two attrib. (class   -    instance)
    city = "minia"
    def __init__(self):
        self.a = 6
    def display(self):  #self.display(self)
        return self.a + 8
    def display(self):  #self.display(self)
        return self.a


t1 = test() #object 
print(t1.a)
print(t1.city)
print(t1.display())

#inheritance
#polyormism محذوف

class test: 
    def __init__(self):
        self.a = 6
    def display(self):  
        return self.a + 8

class testchild(test):
    def display(self):  #overriding
        return self.a


c = testchild()
print(c.display())


#operator overloading

class test: 
    def __init__(self, a = 5):
        self.a = a
    def __add__(self, otherobject):
        return self.a + otherobject.a
        

t1 = test(2)
t2 = test()
print( t1 + t2)


#file open   r   w   a

try:
    file = open("text.txt", "w")
except FileNotFoundError:
    print("not found")


import tkinter

f = tkinter.Tk()

x = tkinter.Label(f, text="hello").pack(side= tkinter.LEFT)




'''                        