· 4 years ago · Sep 07, 2021, 07:10 PM
1import sys
2import math
3import random
4import threading
5import time
6from functools import reduce
7
8# ----- INTRO -----
9# Python files end with the extension .py
10# Print to the console
11# Python statements terminate with a newline
12print("Hello World")
13
14# Accept user input and store it in a variable
15# name = input("What is your name ")
16# print("Hi ", name)
17
18# If you want to extend a statement to multiple
19# lines you can use parentheses or \
20v1 = (
21 1 + 2
22 + 3
23)
24v1 = 1 + 2 \
25 + 3
26
27# Put multiple statements on 1 line
28v1 = 5;
29v1 = v1 - 1
30
31"""
32Multi-line
33Comment
34"""
35
36# ----- VARIABLES -----
37# Variables are names assigned to values
38# The 1st character must be _ or a letter
39# Then you can use letters, numbers or _
40# Variable names are type sensitive
41v2 = 1
42V2 = 2 # v1 is different from V1
43
44# You can assign multiple variables
45v3 = v4 = 20
46
47# ----- DATA TYPES -----
48# Data in Python is dynamically typed and that
49# data type can change
50# All data is an object which I cover later
51# The basic types are integers, floats,
52# complex numbers, strings, booleans
53# Python doesn't have a character type
54
55# How to get the type
56print(type(10))
57
58# There is no limit to the size of integers
59# This is a way to get a practical max size
60print(sys.maxsize)
61
62# Floats are values with decimal values
63# This is how to get a max float
64print(sys.float_info.max)
65
66# But, they are accurate to 15 digits
67f1 = 1.1111111111111111
68f2 = 1.1111111111111111
69f3 = f1 + f2
70print(f3)
71
72# Complex numbers are [real part]+[imaginary part]
73cn1 = 5 + 6j
74
75# Booleans are either True or False
76b1 = True
77
78# Strings are surrounded by ' or "
79str1 = "Escape Sequences \' \t \" \\ and \n"
80
81str2 = '''Triple quoted strings can contain ' and "'''
82
83# You can cast to different types with int, float,
84# str, chr
85print("Cast ", type(int(5.4))) # to int
86print("Cast 2 ", type(str(5.4))) # to string
87print("Cast 3 ", type(chr(97))) # to string
88print("Cast 4 ", type(ord('a'))) # to int
89
90# ----- OUTPUT -----
91# You can define a separator for print
92print(12, 21, 1974, sep='/')
93
94# Eliminate newline
95print("No Newline", end='')
96
97# String formatting %e for exponent
98print("\n%04d %s %.2f %c" % (1, "Derek", 1.234, 'A'))
99
100# ----- MATH -----
101print("5 + 2 =", 5 + 2)
102print("5 - 2 =", 5 - 2)
103print("5 * 2 =", 5 * 2)
104print("5 / 2 =", 5 / 2)
105print("5 % 2 =", 5 % 2)
106print("5 ** 2 =", 5 ** 2)
107print("5 // 2 =", 5 // 2)
108
109# Shortcuts
110i1 = 2
111i1 += 1
112print("i1 ", i1)
113
114# Math Functions
115print("abs(-1) ", abs(-1))
116print("max(5, 4) ", max(5, 4))
117print("min(5, 4) ", min(5, 4))
118print("pow(2, 2) ", pow(2, 2))
119print("ceil(4.5) ", math.ceil(4.5))
120print("floor(4.5) ", math.floor(4.5))
121print("round(4.5) ", round(4.5))
122print("exp(1) ", math.exp(1)) # e**x
123print("log(e) ", math.log(math.exp(1)))
124print("log(100) ", math.log(100, 10)) # Base 10 Log
125print("sqrt(100) ", math.sqrt(100))
126print("sin(0) ", math.sin(0))
127print("cos(0) ", math.cos(0))
128print("tan(0) ", math.tan(0))
129print("asin(0) ", math.asin(0))
130print("acos(0) ", math.acos(0))
131print("atan(0) ", math.atan(0))
132print("sinh(0) ", math.sinh(0))
133print("cosh(0) ", math.cosh(0))
134print("tanh(0) ", math.tanh(0))
135print("asinh(0) ", math.asinh(0))
136print("acosh(pi) ", math.acosh(math.pi))
137print("atanh(0) ", math.atanh(0))
138print("hypot(0) ", math.hypot(10, 10)) # sqrt(x*x + y*y)
139print("radians(0) ", math.radians(0))
140print("degrees(pi) ", math.degrees(math.pi))
141
142# Generate a random int
143print("Random", random.randint(1, 101))
144
145# ----- NaN & inf -----
146# inf is infinity
147print(math.inf > 0)
148
149# NaN is used to represent a number that can't
150# be defined
151print(math.inf - math.inf)
152
153# ----- CONDITIONALS -----
154# Comparison Operators : < > <= >= == !=
155
156# if, else & elif execute different code depending
157# on conditions
158age = 30
159if age > 21:
160 # Python uses indentation to define all the
161 # code that executes if the above is true
162 print("You can drive a tractor trailer")
163elif age >= 16:
164 print("You can drive a car")
165else:
166 print("You can't drive")
167
168# Make more complex conditionals with logical operators
169# Logical Operators : and or not
170if age < 5:
171 print("Stay Home")
172elif (age >= 5) and (age <= 6):
173 print("Kindergarten")
174elif (age > 6) and (age <= 17):
175 print("Grade %d", (age - 5))
176else:
177 print("College")
178
179# Ternary operator in Python
180# condition_true if condition else condition_false
181canVote = True if age >= 18 else False
182
183# ----- STRINGS -----
184# Raw strings ignore escape sequences
185print(r"I'll be ignored \n")
186
187# Combine strings with +
188print("Hello " + "You")
189
190# Get string length
191str3 = "Hello You"
192print("Length ", len(str3))
193
194# Character at index
195print("1st ", str3[0])
196
197# Last character
198print("Last ", str3[-1])
199
200# 1st 3 chrs
201print("1st 3 ", str3[0:3]) # Start, up to not including
202
203# Get every other character
204print("Every Other ", str3[0:-1:2]) # Last is a step
205
206# You can't change an index value like this
207# str3[0] = "a" because strings are immutable
208# (Can't Change)
209# You could do this
210str3 = str3.replace("Hello", "Goodbye")
211print(str3)
212
213# You could also slice front and back and replace
214# what you want to change
215str3 = str3[:8] + "y" + str3[9:]
216print(str3)
217
218# Test if string in string
219print("you" in str3)
220
221# Test if not in
222print("you" not in str3)
223
224# Find first index for match or -1
225print("You Index ", str3.find("you"))
226
227# Trim white space from right and left
228# also lstrip and rstrip
229print(" Hello ".strip())
230
231# Convert a list into a string and separate with
232# spaces
233print(" ".join(["Some", "Words"]))
234
235# Convert string into a list with a defined separator
236# or delimiter
237print("A, string".split(", "))
238
239# Formatted output with f-string
240int1 = int2 = 5
241print(f'{int1} + {int2} = {int1 + int2}')
242
243# To lower and upper case
244print("A String".lower())
245print("A String".upper())
246
247# Is letter or number
248print("abc123".isalnum())
249
250# Is characters
251print("abc".isalpha())
252
253# Is numbers
254print("abc".isdigit())
255
256# ----- LISTS -----
257# Lists can contain mutable pieces of data of
258# varying data types or even functions
259l1 = [1, 3.14, "Derek", True]
260
261# Get length
262print("Length ", len(l1))
263
264# Get value at index
265print("1st", l1[0])
266print("Last", l1[-1])
267
268# Change value
269l1[0] = 2
270
271# Change multiple values
272l1[2:4] = ["Bob", False]
273
274# Insert at index without deleting
275# Also l1.insert(2, "Paul")
276l1[2:2] = ["Paul", 9]
277
278# Add to end (Also l1.extend([5, 6]))
279l2 = l1 + ["Egg", 4]
280
281# Remove a value
282l2.remove("Paul")
283
284# Remove at index
285l2.pop(0)
286print("l2", l2)
287
288# Add to beginning (Also l1.append([5, 6]))
289l2 = ["Egg", 4] + l1
290
291# Multidimensional list
292l3 = [[1, 2], [3, 4]]
293print("[1, 1]", l3[1][1])
294
295# Does value exist
296print("1 Exists", (1 in l1))
297
298# Min & Max
299print("Min ", min([1, 2, 3]))
300print("Max ", max([1, 2, 3]))
301
302# Slice out parts
303print("1st 2", l1[0:2])
304print("Every Other ", l1[0:-1:2])
305print("Reverse ", l1[::-1])
306
307# ----- LOOPS -----
308# While : Execute while condition is True
309w1 = 1
310while w1 < 5:
311 print(w1)
312 w1 += 1
313
314w2 = 0
315while w2 <= 20:
316 if w2 % 2 == 0:
317 print(w2)
318 elif w2 == 9:
319 # Forces the loop to end all together
320 break
321 else:
322 # Shorthand for i = i + 1
323 w2 += 1
324 # Skips to the next iteration of the loop
325 continue
326 w2 += 1
327
328# Cycle through list
329l4 = [1, 3.14, "Derek", True]
330while len(l4):
331 print(l4.pop(0))
332
333# For Loop
334# Allows you to perform an action a set number of times
335# Range performs the action 10 times 0 - 9
336# end="" eliminates newline
337for x in range(0, 10):
338 print(x, ' ', end="")
339print('\n')
340
341# Cycle through list
342l4 = [1, 3.14, "Derek", True]
343for x in l4:
344 print(x)
345
346# You can also define a list of numbers to
347# cycle through
348for x in [2, 4, 6]:
349 print(x)
350
351# You can double up for loops to cycle through lists
352num_list = [[1, 2, 3], [10, 20, 30], [100, 200, 300]]
353
354# ----- ITERATORS -----
355# You can pass an object to iter() which returns
356# an iterator which allows you to cycle
357l5 = [6, 9, 12]
358itr = iter(l5)
359print(next(itr)) # Grab next value
360
361# ----- RANGES -----
362# The range() function creates integer iterables
363print(list(range(0, 5)))
364
365# You can define step
366print(list(range(0, 10, 2)))
367
368for x in range(0, 3):
369 for y in range(0, 3):
370 print(num_list[x][y])
371
372# ----- TUPLES -----
373# Tuples are just like lists except they are
374# immutable
375t1 = (1, 3.14, "Derek", False)
376
377# Get length
378print("Length ", len(t1))
379
380# Get value / values
381print("1st", t1[0])
382print("Last", t1[-1])
383print("1st 2", t1[0:2])
384print("Every Other ", t1[0:-1:2])
385print("Reverse ", t1[::-1])
386
387# Everything you can do with lists you can do with
388# tuples as long as you don't change values
389
390# ----- DICTIONARIES -----
391# Dictionaries are lists of key / value pairs
392# Keys and values can use any data type
393# Duplicate keys aren't allowed
394heroes = {
395 "Superman": "Clark Kent",
396 "Batman": "Bruce Wayne"
397}
398
399villains = dict([
400 ("Lex Luthor", "Lex Luthor"),
401 ("Loki", "Loki")
402])
403
404print("Length", len(heroes))
405
406# Get value by key
407# Also heroes.get("Superman")
408print(heroes["Superman"])
409
410# Add more
411heroes["Flash"] = "Barry Allan"
412
413# Change a value
414heroes["Flash"] = "Barry Allen"
415
416# Get list of tuples
417print(list(heroes.items()))
418
419# Get list of keys and values
420print(list(heroes.keys()))
421print(list(heroes.values()))
422
423# Delete
424del heroes["Flash"]
425
426# Remove a key and return it
427print(heroes.pop("Batman"))
428
429# Search for key
430print("Superman" in heroes)
431
432# Cycle through a dictionary
433for k in heroes:
434 print(k)
435
436for v in heroes.values():
437 print(v)
438
439# Formatted print with dictionary mapping
440d1 = {"name": "Bread", "price": .88}
441print("%(name)s costs $%(price).2f" % d1)
442
443# ----- SETS -----
444# Sets are lists that are unordered, unique
445# and while values can change those values
446# must be immutable
447s1 = set(["Derek", 1])
448
449s2 = {"Paul", 1}
450
451# Size
452print("Length", len(s2))
453
454# Join sets
455s3 = s1 | s2
456print(s3)
457
458# Add value
459s3.add("Doug")
460
461# Remove value
462s3.discard("Derek")
463
464# Remove random value
465print("Random", s3.pop())
466
467# Add values in s2 to s3
468s3 |= s2
469
470# Return common values (You can include multiple
471# sets as attributes)
472print(s1.intersection(s2))
473
474# All unique values
475print(s1.symmetric_difference(s2))
476
477# Values in s1 but not in s2
478print(s1.difference(s2))
479
480# Clear values
481s3.clear()
482
483# Frozen sets can't be edited
484s4 = frozenset(["Paul", 7])
485
486
487# ----- FUNCTIONS -----
488# Functions provide code reuse, organization
489# and much more
490# Add 2 values using 1 as default
491# You can define the data type using function
492# annotations
493def get_sum(num1: int = 1, num2: int = 1):
494 return num1 + num2
495print(get_sum(5, 4))
496
497# Accept multiple values
498def get_sum2(*args):
499 sum = 0
500 for arg in args:
501 sum += arg
502 return sum
503print(get_sum2(1, 2, 3, 4))
504
505# Return multiple values
506def next_2(num):
507 return num + 1, num + 2
508i1, i2 = next_2(5)
509print(i1, i2)
510
511# A function that makes a function that
512# multiplies by the given value
513def mult_by(num):
514 # You can create anonymous (unnamed functions)
515 # with lambda
516 return lambda x: x * num
517print("3 * 5 =", (mult_by(3)(5)))
518
519# Pass a function to a function
520def mult_list(list, func):
521 for x in list:
522 print(func(x))
523mult_by_4 = mult_by(4)
524mult_list(list(range(0, 5)), mult_by_4)
525
526# Create list of functions
527power_list = [lambda x: x ** 2,
528 lambda x: x ** 3,
529 lambda x: x ** 4]
530
531# ----- MAP -----
532# Map is used to execute a function on a list
533one_to_4 = range(1, 5)
534times2 = lambda x: x * 2
535print(list(map(times2, one_to_4)))
536
537# ----- FILTER -----
538# Filter selects items based on a function
539# Print out the even values from a list
540print(list(filter((lambda x: x % 2 == 0), range(1, 11))))
541
542# ----- REDUCE -----
543# Reduce receives a list and returns a single
544# result
545# Add up the values in a list
546print(reduce((lambda x, y: x + y), range(1, 6)))
547
548# ----- EXCEPTION HANDLING -----
549# You can handle errors that would otherwise
550# crash your program
551# By giving the while a value of True it will
552# cycle until a break is reached
553while True:
554
555 # If we expect an error can occur surround
556 # potential error with try
557 try:
558 number = int(input("Please enter a number : "))
559 break
560
561 # The code in the except block provides
562 # an error message to set things right
563 # We can either target a specific error
564 # like ValueError
565 except ValueError:
566 print("You didn't enter a number")
567
568 # We can target all other errors with a
569 # default
570 except:
571 print("An unknown error occurred")
572
573print("Thank you for entering a number")
574
575# ----- FILE IO -----
576# We can save and read data from files
577# We start the code with with which guarantees
578# the file will be closed if the program crashes
579# mode w overwrites file
580# mode a appends
581with open("mydata.txt", mode="w", encoding="utf-8") \
582 as myFile:
583 # You can write to the file with write
584 # It doesn't add a newline
585 myFile.write("Some random text\nMore random text\nAnd some more")
586
587# Open a file for reading
588with open("mydata.txt", encoding="utf-8") as myFile:
589 # Use read() to get everything at once
590 print(myFile.read())
591
592# Find out if the file is closed
593print(myFile.closed)
594
595# ----- CLASSES OBJECTS -----
596# Real world objects have
597# attributes : height, weight
598# capabilities : run, eat
599
600# Classes are blueprints for creating objects
601class Square:
602 # init is used to set values for each Square
603 def __init__(self, height="0", width="0"):
604 self.height = height
605 self.width = width
606
607 # This is the getter
608 # self is used to refer to an object that
609 # we don't possess a name for
610 @property
611 def height(self):
612 print("Retrieving the height")
613
614 # Put a __ before this private field
615 return self.__height
616
617 # This is the setter
618 @height.setter
619 def height(self, value):
620
621 # We protect the height from receiving
622 # a bad value
623 if value.isdigit():
624
625 # Put a __ before this private field
626 self.__height = value
627 else:
628 print("Please only enter numbers for height")
629
630 # This is the getter
631 @property
632 def width(self):
633 print("Retrieving the width")
634 return self.__width
635
636 # This is the setter
637 @width.setter
638 def width(self, value):
639 if value.isdigit():
640 self.__width = value
641 else:
642 print("Please only enter numbers for width")
643
644 def get_area(self):
645 return int(self.__width) * int(self.__height)
646
647# Create a Square object
648square = Square()
649square.height = "10"
650square.width = "10"
651print("Area", square.get_area())
652
653# ----- INHERITANCE & POLYMORPHISM-----
654# When a class inherits from another it gets all
655# its fields and methods and can change as needed
656class Animal:
657 def __init__(self, name="unknown", weight=0):
658 self.__name = name
659 self.__weight = weight
660
661 @property
662 def name(self, name):
663 self.__name = name
664
665 def make_noise(self):
666 return "Grrrrr"
667
668 # Used to cast to a string type
669 def __str__(self):
670 return "{} is a {} and says {}".format (self.__name, type(self).__name__, self.make_noise())
671
672 # Magic methods are used for operator
673 # overloading
674 # Here I'll define how to evaluate greater
675 # than between 2 Animal objects
676 def __gt__(self, animal2):
677 if self.__weight > animal2.__weight:
678 return True
679 else:
680 return False
681 # Other Magic Methods
682 # __eq__ : Equal
683 # __ne__ : Not Equal
684 # __lt__ : Less Than
685 # __gt__ : Greater Than
686 # __le__ : Less Than or Equal
687 # __ge__ : Greater Than or Equal
688 # __add__ : Addition
689 # __sub__ : Subtraction
690 # __mul__ : Multiplication
691 # __div__ : Division
692 # __mod__ : Modulus
693
694# Dog inherits everything from Animal
695class Dog(Animal):
696 def __init__(self, name="unknown", owner="unknown", weight=0):
697 # Have the super class handle initializing
698 Animal.__init__(self, name, weight)
699 self.__owner = owner
700
701 # Overwrite str
702 def __str__(self):
703 # How to call super class methods
704 return super().__str__() + " and is owned by " + \
705 self.__owner
706
707animal = Animal("Spot", 100)
708print(animal)
709
710dog = Dog("Bowser", "Bob", 150)
711print(dog)
712
713# Test the magic method
714print(animal > dog)
715
716# Polymorphism in Python works differently from
717# other languages in that functions accept any
718# object and expect that object to provide the
719# needed method
720
721# This isn't something to dwell on. Just know
722# that if you call on a method for an object
723# that the method just needs to exist for
724# that object to work.
725
726# ----- THREADS -----
727# Threads are blocks of code that takes turns
728# executing
729def execute_thread(i):
730 # strftime or string formatted time allows you to
731 # define how the time is displayed.
732 # You could include the date with
733 # strftime("%Y-%m-%d %H:%M:%S", gmtime())
734
735 # Print when the thread went to sleep
736 print("Thread {} sleeps at {}".format(i,
737 time.strftime("%H:%M:%S", time.gmtime())))
738
739 # Generate a random sleep period of between 1 and
740 # 5 seconds
741 rand_sleep_time = random.randint(1, 5)
742
743 # Pauses execution of code in this function for
744 # a few seconds
745 time.sleep(rand_sleep_time)
746
747 # Print out info after the sleep time
748 print("Thread {} stops sleeping at {}".format(i,
749 time.strftime("%H:%M:%S", time.gmtime())))
750
751for i in range(10):
752 # Each time through the loop a Thread object is created
753 # You pass it the function to execute and any
754 # arguments to pass to that method
755 # The arguments passed must be a sequence which
756 # is why we need the comma with 1 argument
757 thread = threading.Thread(target=execute_thread, args=(i,))
758 thread.start()
759
760 # Display active threads
761 # The extra 1 is this for loop executing in the main
762 # thread
763 print("Active Threads :", threading.activeCount())
764
765 # Returns a list of all active thread objects
766 print("Thread Objects :", threading.enumerate())
767
768# Regular expressions allow you to locate and change
769# strings in very powerful ways.
770# They work in almost exactly the same way in every
771# programming language as well.
772
773# Regular Expressions (Regex) are used to
774# 1. Search for a specific string in a large amount of data
775# 2. Verify that a string has the proper format (Email, Phone #)
776# 3. Find a string and replace it with another string
777# 4. Format data into the proper form for importing for example
778
779# import the Regex module
780import re
781
782# ---------- Was a Match Found ----------
783
784# Search for ape in the string
785if re.search("ape", "The ape was at the apex"):
786 print("There is an ape")
787
788# ---------- Get All Matches ----------
789
790# findall() returns a list of matches
791# . is used to match any 1 character or space
792allApes = re.findall("ape.", "The ape was at the apex")
793
794for i in allApes:
795 print(i)
796
797# finditer returns an iterator of matching objects
798# You can use span to get the location
799
800theStr = "The ape was at the apex"
801
802for i in re.finditer("ape.", theStr):
803
804 # Span returns a tuple
805 locTuple = i.span()
806
807 print(locTuple)
808
809 # Slice the match out using the tuple values
810 print(theStr[locTuple[0]:locTuple[1]])
811
812# Here I'll show you how to work with SQLite databases
813# in Python
814
815# A database makes it easy for you to organize your
816# data for storage and fast searching
817import sqlite3
818import sys
819import csv
820def printDB():
821 # To retrieve data from a table use SELECT followed
822 # by the items to retrieve and the table to
823 # retrieve from
824
825 try:
826 result = theCursor.execute("SELECT id, FName, LName, Age, Address, Salary, HireDate FROM Employees")
827
828 # You receive a list of lists that hold the result
829 for row in result:
830 print("ID :", row[0])
831 print("FName :", row[1])
832 print("LName :", row[2])
833 print("Age :", row[3])
834 print("Address :", row[4])
835 print("Salary :", row[5])
836 print("HireDate :", row[6])
837
838 except sqlite3.OperationalError:
839 print("The Table Doesn't Exist")
840
841 except:
842 print("Couldn't Retrieve Data From Database")
843
844# ---------- END OF FUNCTIONS ----------
845
846# connect() will open an SQLite database, or if it
847# doesn't exist it will create it
848# The file appears in the same directory as this
849# Python file
850db_conn = sqlite3.connect('test.db')
851
852print("Database Created")
853
854# A cursor is used to traverse the records of a result
855theCursor = db_conn.cursor()
856
857# execute() executes a SQL command
858# We organize our data in tables by defining their
859# name and the data type for the data
860
861# We define the table name
862# A primary key is a unique value that differentiates
863# each row of data in our table
864# The primary key will auto increment each time we
865# add a new Employee
866# If a piece of data is marked as NOT NULL, that means
867# it must have a value to be valid
868
869# NULL is NULL and stands in for no value
870# INTEGER is an integer
871# TEXT is a string of variable length
872# REAL is a float
873# BLOB is used to store binary data
874
875# You can delete a table if it exists like this
876# db_conn.execute("DROP TABLE IF EXISTS Employees")
877# db_conn.commit()
878
879try:
880 db_conn.execute("CREATE TABLE Employees(ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, FName TEXT NOT NULL, LName TEXT NOT NULL, Age INT NOT NULL, Address TEXT, Salary REAL, HireDate TEXT);")
881
882 db_conn.commit()
883
884 print("Table Created")
885
886except sqlite3.OperationalError:
887 print("Table couldn't be Created")
888
889
890# To insert data into a table we use INSERT INTO
891# followed by the table name and the item name
892# and the data to assign to those items
893
894db_conn.execute("INSERT INTO Employees (FName, LName, Age, Address, Salary, HireDate)"
895 "VALUES ('Derek', 'Banas', 41, '123 Main St', '500,000', date('now'))")
896
897db_conn.commit()
898
899print("Employee Entered")
900
901# Print out all the data in the database
902printDB()
903
904# Closes the database connection
905db_conn.close()
906
907# ——- myfunc.py ——-
908
909# ---------- RECURSIVE FUNCTIONS ----------
910# A function that refers to itself is a recursive function
911
912# Calculating factorials is commonly done with a recursive
913# function 3! = 3 * 2 * 1
914def factorial(num):
915 # Every recursive function must contain a condition
916 # when it ceases to call itself
917 if num <= 1:
918 return 1
919 else:
920
921 result = num * factorial(num - 1)
922 return result
923
924# 1st : result = 4 * factorial(3) = 4 * 6 = 24
925# 2nd : result = 3 * factorial(2) = 3 * 2 = 6
926# 3rd : result = 2 * factorial(1) = 2 * 1 = 2
927
928# ——— MODULES ———
929import myfunc
930print(myfunc.factorial(4))
931
932# OR
933
934from myfunc import factorial
935print(factorial(4))
936
937# ——— GUI DEVELOPMENT WITH TKINTER ———
938
939from tkinter import *
940from tkinter import ttk
941
942class Calculator:
943
944 # Stores the current value to display in the entry
945 calc_value = 0.0
946
947 # Will define if this was the last math button clicked
948 div_trigger = False
949 mult_trigger = False
950 add_trigger = False
951 sub_trigger = False
952
953 # Called anytime a number button is pressed
954 def button_press(self, value):
955
956 # Get the current value in the entry
957 entry_val = self.number_entry.get()
958
959 # Put the new value to the right of it
960 # If it was 1 and 2 is pressed it is now 12
961 # Otherwise the new number goes on the left
962 entry_val += value
963
964 # Clear the entry box
965 self.number_entry.delete(0, "end")
966
967 # Insert the new value going from left to right
968 self.number_entry.insert(0, entry_val)
969
970 # Returns True or False if the string is a float
971 def isfloat(self, str_val):
972 try:
973
974 # If the string isn't a float float() will throw a
975 # ValueError
976 float(str_val)
977
978 # If there is a value you want to return use return
979 return True
980 except ValueError:
981 return False
982
983 # Handles logic when math buttons are pressed
984 def math_button_press(self, value):
985
986 # Only do anything if entry currently contains a number
987 if self.isfloat(str(self.number_entry.get())):
988
989 # make false to cancel out previous math button click
990 self.add_trigger = False
991 self.sub_trigger = False
992 self.mult_trigger = False
993 self.div_trigger = False
994
995 # Get the value out of the entry box for the calculation
996 self.calc_value = float(self.entry_value.get())
997
998 # Set the math button click so when equals is clicked
999 # that function knows what calculation to use
1000 if value == "/":
1001 print("/ Pressed")
1002 self.div_trigger = True
1003 elif value == "*":
1004 print("* Pressed")
1005 self.mult_trigger = True
1006 elif value == "+":
1007 print("+ Pressed")
1008 self.add_trigger = True
1009 else:
1010 print("- Pressed")
1011 self.sub_trigger = True
1012
1013 # Clear the entry box
1014 self.number_entry.delete(0, "end")
1015
1016 # Performs a mathematical operation by taking the value before
1017 # the math button is clicked and the current value. Then perform
1018 # the right calculation by checking what math button was clicked
1019 # last
1020 def equal_button_press(self):
1021
1022 # Make sure a math button was clicked
1023 if self.add_trigger or self.sub_trigger or self.mult_trigger or self.div_trigger:
1024
1025 if self.add_trigger:
1026 solution = self.calc_value + float(self.entry_value.get())
1027 elif self.sub_trigger:
1028 solution = self.calc_value - float(self.entry_value.get())
1029 elif self.mult_trigger:
1030 solution = self.calc_value * float(self.entry_value.get())
1031 else:
1032 solution = self.calc_value / float(self.entry_value.get())
1033
1034 print(self.calc_value, " ", float(self.entry_value.get()),
1035 " ", solution)
1036
1037 # Clear the entry box
1038 self.number_entry.delete(0, "end")
1039
1040 self.number_entry.insert(0, solution)
1041
1042
1043 def __init__(self, root):
1044 # Will hold the changing value stored in the entry
1045 self.entry_value = StringVar(root, value="")
1046
1047 # Define title for the app
1048 root.title("Calculator")
1049
1050 # Defines the width and height of the window
1051 root.geometry("430x220")
1052
1053 # Block resizing of Window
1054 root.resizable(width=False, height=False)
1055
1056 # Customize the styling for the buttons and entry
1057 style = ttk.Style()
1058 style.configure("TButton",
1059 font="Serif 15",
1060 padding=10)
1061
1062 style.configure("TEntry",
1063 font="Serif 18",
1064 padding=10)
1065
1066 # Create the text entry box
1067 self.number_entry = ttk.Entry(root,
1068 textvariable=self.entry_value, width=50)
1069 self.number_entry.grid(row=0, columnspan=4)
1070
1071 # ----- 1st Row -----
1072
1073 self.button7 = ttk.Button(root, text="7", command=lambda: self.button_press('7')).grid(row=1, column=0)
1074
1075 self.button8 = ttk.Button(root, text="8", command=lambda: self.button_press('8')).grid(row=1, column=1)
1076
1077 self.button9 = ttk.Button(root, text="9", command=lambda: self.button_press('9')).grid(row=1, column=2)
1078
1079 self.button_div = ttk.Button(root, text="/", command=lambda: self.math_button_press('/')).grid(row=1, column=3)
1080
1081 # ----- 2nd Row -----
1082
1083 self.button4 = ttk.Button(root, text="4", command=lambda: self.button_press('4')).grid(row=2, column=0)
1084
1085 self.button5 = ttk.Button(root, text="5", command=lambda: self.button_press('5')).grid(row=2, column=1)
1086
1087 self.button6 = ttk.Button(root, text="6", command=lambda: self.button_press('6')).grid(row=2, column=2)
1088
1089 self.button_mult = ttk.Button(root, text="*", command=lambda: self.math_button_press('*')).grid(row=2, column=3)
1090
1091 # ----- 3rd Row -----
1092
1093 self.button1 = ttk.Button(root, text="1", command=lambda: self.button_press('1')).grid(row=3, column=0)
1094
1095 self.button2 = ttk.Button(root, text="2", command=lambda: self.button_press('2')).grid(row=3, column=1)
1096
1097 self.button3 = ttk.Button(root, text="3", command=lambda: self.button_press('3')).grid(row=3, column=2)
1098
1099 self.button_add = ttk.Button(root, text="+", command=lambda: self.math_button_press('+')).grid(row=3, column=3)
1100
1101 # ----- 4th Row -----
1102
1103 self.button_clear = ttk.Button(root, text="AC", command=lambda: self.button_press('AC')).grid(row=4, column=0)
1104
1105 self.button0 = ttk.Button(root, text="0", command=lambda: self.button_press('0')).grid(row=4, column=1)
1106
1107 self.button_equal = ttk.Button(root, text="=", command=lambda: self.equal_button_press()).grid(row=4, column=2)
1108
1109 self.button_sub = ttk.Button(root, text="-", command=lambda: self.math_button_press('-')).grid(row=4, column=3)
1110
1111# Get the root window object
1112root = Tk()
1113
1114# Create the calculator
1115calc = Calculator(root)
1116
1117# Run the app until exited
1118root.mainloop()