Categories
All

Time Tracking

python working time toggl tracking

http://www.online-stopwatch.com/cash-clock/

import sys
import datetime
import keyboard 
import time

timeInSeconds = 0
tillNowTime = 0
startedTime = str(datetime.datetime.now())
rate = 1.2
eq = 0

while True:
	if keyboard.is_pressed("esc"):
		break

	tillNowTime = str(datetime.timedelta(seconds = timeInSeconds))
	eq += rate
	sys.stdout.write("Started at: %s  |  Till now: %s , %s[X]\r" %( startedTime, tillNowTime, str(eq)) )
	sys.stdout.flush()
	timeInSeconds += 1
	
	time.sleep(1)	
	
print("\n--------\nEnded at: " + str(datetime.datetime.now()) + " | Total: " + str(tillNowTime) )
Categories
All

CLIPS Diagnoser Task

main.clp

; Diagnoser | Expert System task 4cs

;
; run:
; CLIPS> (load C:\PATH_DIR\main.clp)
; CLIPS> (run)


(deffunction print-parts()
	(printout t crlf "--= Diagnoser =--" crlf crlf)
	(printout t "> eye (available)" crlf)
	(printout t "> nose (available)" crlf)
	(printout t "> ear" crlf)
	(printout t "> mouth" crlf)
	(printout t "> shoulder" crlf)
	(printout t "> neck" crlf)
	(printout t "> hand" crlf)
	(printout t "> arm" crlf)
	(printout t "> elbow" crlf)
	(printout t "> waist" crlf)
	(printout t "> stomack" crlf)
	(printout t "> leg" crlf)
	(printout t "> foot" crlf)
	(printout t "Choose part: ")
)

(defglobal  ?*sum* = 0)

; vvvvvvvvvvvvvvvvvv
(defrule START_POINT
	?f <- (initial-fact)
=>
	(load-facts "kb.clp")
	(retract ?f)
	(print-parts)
	(assert (ask-part (read)))
)

(defrule ask-part
	?f <- (ask-part ?part)
	(ask-part ?)
=>
	(printout t "-->> " ?part ":" crlf)
	(assert (ask-questions ?part))
)

(defrule ask-questions
	?f <- (ask-questions ?part)
	?f2 <- (question ?part ?perc $?text)
	(ask-questions ?)
=>
	(printout t $?text " [yes, no] ")
	(bind ?ans (read))
	(if (member$ ?ans (create$ yes) )
		then (bind ?*sum* (+ ?*sum* ?perc))
	)
	(assert (result ?part))
)

(defrule result
	?f <- (result ?part)
	(advice ?part $?text)
	(result ?)
=>
	(retract ?f)
	(if (> ?*sum* 0)
		then 
			(printout t crlf "danger percentage: " ?*sum* "%" crlf)
			(printout t $?text crlf crlf)
		else 
			(printout t crlf "you are ok!" crlf crlf)
	)
)

kb.clp

; Diagnoser | Knowledge base
;
; Expert person(ex. doctor) will add symptoms here


(question nose 50 Is there nose runny?)
(question nose 20 Is there sneezing?)
(question nose 30 is there sore throat?)
; برد - دكتور انف واذن
(advice nose Maybe it's cold go to otolaryngologist doctor)


(question eye 40 Is there friction in the eye?)
(question eye 40 Is eyes are red?)
(question eye 20 Are there tears?)
; التهاب فى العين- دكتور عيون
(advice eye Maybe it's Inflammation go to ophthalmologist doctor)

 
Categories
All

MD5 [En/De]crypter

More than 1.000.000 words in our database. 🙂

http://www.md5.epizy.com

The MD5 algorithm is a widely used hash function producing a 128-bit hash value.
Although MD5 was initially designed to be used as a cryptographic hash function,
it has been found to suffer from extensive vulnerabilities.

Categories
All

Police Traffic Control

Police Traffic Control | Arduino and ASP.NET project.
This project helps police to control traffic and catch the suspects easily.

code.ino

/*
 * Police Traffic Control | Arduino and ASP.NET project.
 * This project helps police to control traffic and catch the suspects easily.
 * 
 * author: khaled alam
 */

 
#include <Servo.h>

// pins
const int greenLed = 4;
const int redLed = 2;
const int buzzer = 5;
const int lightSensor = A0;
const int servoPin = 9;

//vars changeable
int lightValue;
int sensorValue;
int continueStopping = -1;
char incomingFromSerial;

//serial const signals
const char OPEN_GATE = '1';
const char CLOSE_GATE = '2';
const char POLICE_SAY_STOP = '3';
const char BUZZ_ON = '4';
const char BUZZ_OFF = '5';
const char GREEN_ON = '6';
const char GREEN_OFF = '7';
const char RED_ON = '8';
const char RED_OFF = '9';

Servo servo;

void setup()
{
  Serial.begin(9600);
  servo.attach(servoPin);
  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop()
{

  while(Serial.available() > 0)
  {
    //read serial come from ASP.NET
    incomingFromSerial = Serial.read();

    //if police ask driver to stop
    if (incomingFromSerial == POLICE_SAY_STOP)
    {
      continueStopping = 1;
      offCorrectLed();
      onWrongLed();
      openGate();
      detect(); 
    }

    // Do action based on serial signal send from ASP.NET
    // manual actions:
    if(incomingFromSerial == CLOSE_GATE)
    {
      continueStopping = -1;
      closeGate();
      offCorrectLed();
      onWrongLed();
    }
    else if (incomingFromSerial == OPEN_GATE)
    {
      continueStopping = -1;
      openGate();
      offWrongLed();
      onCorrectLed();
    }else if (incomingFromSerial == BUZZ_ON)
    {
      continueStopping = 1;
      turnOnBuzzer();
    }else if (incomingFromSerial == BUZZ_OFF)
    {
      continueStopping = -1;
      noTone(buzzer);
    }else if (incomingFromSerial == GREEN_ON)
    {
      digitalWrite(greenLed, HIGH);    
    }else if (incomingFromSerial == GREEN_OFF)
    {
      digitalWrite(greenLed, LOW);
    }else if (incomingFromSerial == RED_ON)
    {
      digitalWrite(redLed, HIGH);
    }else if (incomingFromSerial == RED_OFF)
    {
      digitalWrite(redLed, LOW);
    }
    delay(100); // wait 100 milliseconds (0.1 second)
    Serial.flush();
  }

}

/* 
 *  detect function use as a loop to check
 * if driver follow police order and stop or not 
 */
void detect()
{
  //while police ask driver to stop
  while(continueStopping == 1)
  {
    //check if driver run before police allow
    if ( pass() )
    {
      closeGate();
      turnOnBuzzer();
      Serial.println("Catch Now..");
      break;
    }
    onWrongLed();
  }
}

void onCorrectLed()
{
  digitalWrite(greenLed, HIGH);
}

void offCorrectLed()
{
  digitalWrite(greenLed, LOW);
}

void onWrongLed()
{
  digitalWrite(redLed, HIGH);
}

void offWrongLed()
{
  digitalWrite(redLed, LOW);
}

void turnOnBuzzer()
{
  while (continueStopping == 1)
  {
    //read from ASP.NET during police stop order
    incomingFromSerial = Serial.read();
    
    tone(buzzer, 1200); // << turn on buzzer
    
    // condition to stop buzzer
    if(incomingFromSerial == OPEN_GATE || 
        incomingFromSerial == CLOSE_GATE ||
        incomingFromSerial == POLICE_SAY_STOP ||
        incomingFromSerial == BUZZ_OFF)
    {
      if (incomingFromSerial != BUZZ_OFF)openGate();
      noTone(buzzer);
      continueStopping = -1;
    }
    delay(60);
  }
}

//check if any car cover light sensor or not
boolean pass()
{
  sensorValue = analogRead(lightSensor);
  lightValue = map(sensorValue, 0, 1023, 0, 255); 

  // increase 8 to increase sensitivity)
  if (lightValue <= 8)return true;
  return false;
}

void openGate()
{
  servo.write(0);
}

void closeGate()
{
  servo.write(90);
}

void debug()
{
  Serial.print("Light Value = ");
  Serial.println(lightValue);
}

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Police_Traffic_Control
{
    public partial class _Default : Page
    {
        public static SerialPort sp;

        // Signals
        const string OPEN_GATE       = "1";
        const string CLOSE_GATE      = "2";
        const string POLICE_SAY_STOP = "3";
        const string BUZZ_ON         = "4";
        const string BUZZ_OFF        = "5";
        const string GREEN_ON        = "6";
        const string GREEN_OFF       = "7";
        const string RED_ON          = "8";
        const string RED_OFF         = "9";

        //Images
        const string welcomeImg = "~/imgs/welcome.png";
        const string openImg    = "~/imgs/gateO.jpg";
        const string closeImg   = "~/imgs/gateC.jpg";
        // etc...


        protected void Page_Load(object sender, EventArgs e)
        {
            sp = new SerialPort();
            sp.PortName = "COM3"; // change port name(if change usb pos.)
            sp.BaudRate = 9600;
            sp.Parity = Parity.None;
            sp.DataBits = 8;
            sp.StopBits = StopBits.One;
            sp.ReadTimeout = 1000;
            StatusImage.ImageUrl = welcomeImg; // default welcome img
        }

        // Change images action examples
        protected void changeImage1(object sender, EventArgs e)
        {
            StatusImage.ImageUrl = openImg;
        }
        protected void changeImage2(object sender, EventArgs e)
        {
            StatusImage.ImageUrl = closeImg;
        }
        protected void changeImageProp(object sender, EventArgs e)
        {
            StatusImage.Width = 250;
            StatusImage.Height = 300;
            StatusImage.ImageAlign = ImageAlign.Bottom;
            //...
        }



        protected void stopNow(object sender, EventArgs e) //send command to uno to open gate and turn on passing detection
        {
            GateStatus.Text = "<b style='background-color:yellow;'> >>> </b>Police is Asking Driver To Stop!";

            // Change image ex. :
            StatusImage.ImageUrl      =     openImg; 
            // add alertImg instead of openImg ^ for example

            if(!sp.IsOpen)sp.Open();
            sp.Write(POLICE_SAY_STOP); sp.Close();
        }


        protected void openGate(object sender, EventArgs e) //send command to uno to open gate
        {
            GateStatus.Text = "<b style='background-color:green;'> >>> </b>Gate Opened!";
            if (!sp.IsOpen)sp.Open();
            sp.Write(OPEN_GATE); sp.Close();
        }


        protected void closeGate(object sender, EventArgs e) //send command to uno to close gate
        {
            GateStatus.Text = "<b style='background-color:red;'> >>> </b> Gate Closed!";
            if (!sp.IsOpen) sp.Open();
            sp.Write(CLOSE_GATE); sp.Close();

        }

        protected void buzzOn(object sender, EventArgs e) //send command to uno to turn on buzz
        {
            GateStatus.Text = "<b style='background-color:brown;'> >>> </b> Buzz On!";
            if (!sp.IsOpen) sp.Open();
            sp.Write(BUZZ_ON); sp.Close();
        }


        protected void buzzOff(object sender, EventArgs e) //send command to uno to turn off buzz
        {
            GateStatus.Text = "<b style='background-color:gray;'> >>> </b> Buzz Off!";
            if (!sp.IsOpen) sp.Open();
            sp.Write(BUZZ_OFF); sp.Close();
        }


        protected void greenLedOn(object sender, EventArgs e) //send command to uno to turn on green led
        {
            GateStatus.Text = "<b style='background-color:green;'> >>> </b> Green Led On!";
            if (!sp.IsOpen) sp.Open();
            sp.Write(GREEN_ON); sp.Close();
        }


        protected void greenLedOff(object sender, EventArgs e) //send command to uno to turn off green led
        {
            GateStatus.Text = "<b style='background-color:green;'> >>> </b> Green Led Off!";
            if (!sp.IsOpen) sp.Open();
            sp.Write(GREEN_OFF); sp.Close();
        }


        protected void redLedOn(object sender, EventArgs e) //send command to uno to turn on red led
        {
            GateStatus.Text = "<b style='background-color:red;'> >>> </b> Red Led On!";
            if (!sp.IsOpen) sp.Open();
            sp.Write(RED_ON); sp.Close();
        }


        protected void redLedOff(object sender, EventArgs e) //send command to uno to turn off red led
        {
            GateStatus.Text = "<b style='background-color:red;'> >>> </b> Red Led Off!";
            if (!sp.IsOpen) sp.Open();
            sp.Write(RED_OFF); sp.Close();
        }

    }
}
Categories
All

PyShifterPro

Python and prolog encryption project based on “caesar cipher” encryption technique.

How to use:

  • in terminal: python PrologGenerator.py :> prologCode.pl
  • run prolog code via terminal(swipl prologCode.pl) or gui then use:
    • shift(a, X).
    • hideChar(a).
    • showChar(a).
    • guessChar(a).
    • hideString(test).
    • showString(nkdohg).
    • guessString(abc).
    • readFile.
    • dfs(a, X, z). continue pressing ;

for windows users: download and use python and prolog gui.

Examples:

#Ex.1 walk start from a with key = 3

?- walk(a,X,z).
X = d ;
X = g ;
X = j ;
X = m ;
X = p ;
X = s ;
X = v ;
X = y ;
X = b ;
X = e ;
X = h ;
X = k ;
X = n ;
X = q ;
X = t ;
X = w ;
X = z ;
X = c ;
false.

#Ex.2 encrypt string met3cs with key = 3

?- hideString(met3cs).
phw6fv
true.

#Ex.3 decrypt string phw6fv with key = 3

?- showString(phw6fv).
met3cs
true.

#Ex.4 encrypt char z with key = 3

?- hideChar(z).
c
true.

Files Structure:

examples
   \ input.txt
   \ prologCode.pl
PrologGenerator.py
input.txt
prologCode.pl

——-

prologCode.pl

shift(a, d).
shift(b, e).
shift(c, f).
shift(d, g).
shift(e, h).
shift(f, i).
shift(g, j).
shift(h, k).
shift(i, l).
shift(j, m).
shift(k, n).
shift(l, o).
shift(m, p).
shift(n, q).
shift(o, r).
shift(p, s).
shift(q, t).
shift(r, u).
shift(s, v).
shift(t, w).
shift(u, x).
shift(v, y).
shift(w, z).
shift(x, a).
shift(y, b).
shift(z, c).
shift(0, 3).
shift(1, 4).
shift(2, 5).
shift(3, 6).
shift(4, 7).
shift(5, 8).
shift(6, 0).
shift(7, 1).
shift(8, 2).
shift(9, 3).
shift(., *).
shift(*,.).


hideChar(X):- shift(X,Y), write(Y).
showChar(X):- shift(Y,X), write(Y).
guessChar(X):- shift(X,Y), shift(Z,X), write("maybe: "), write(Y), write("\nOR\nmaybe: "), write(Z), write('\n=========\n').


numToCharEnc(Number, Character) :- name(Character, [Number]), hideChar(Character).
numToCharDec(Number, Character) :- name(Character, [Number]), showChar(Character).
hideString(String) :- name(String, Xs), maplist( numToCharEnc, Xs, _Characters ).
showString(String) :- name(String, Xs), maplist( numToCharDec, Xs, _Characters ).
guessString(String) :- write("maybe: "), hideString(String), write("\nOR\nmaybe: "), showString(String), write('\n=========\n').


readFile :-
open('input.txt', read, Str), read_file(Str,Lines), close(Str), write(Lines), nl.
read_file(Stream,[]) :- at_end_of_stream(Stream).
read_file(Stream,[X|L]) :- \+ at_end_of_stream(Stream), read(Stream,X), write(X), write(' : '), write('\n'), guessString(X), write('\n'), read_file(Stream,L).


walk(X, Z, _ORG):- shift(X,Z).
walk(X, Z, _ORG):- _ORG \= X -> shift(X,Y), walk(Y, Z, _ORG).

input.txt

khaled'.
'000000'.
'a.goal'.
'without.a'.
'plan.is'.
'just.a.wish.'.

PrologGenerator.py

# Encryption and Decryption Project using Prolog and Python
# \_based on "Caesar cipher" encryption technique..
#
# Author: Khaled Alam


import string



# START Configuration(changeable): >>>>>>>>>>>>>>>>>>>>>>>>>>>

shiftingKey = 3      # << 3 default(Caesar cipher)
factName = 'shift'
bothPredicateName = 'guess'
encryptPredicateName = 'hide'
decryptPredicateName = 'show'


factLower = True
factUpper = False  # not handled
factDigits = True

inputFileName = 'input.txt'


# END Configuration(changeable): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>



# START BUILD THE FACTS BASE.. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#lower chars:
if factLower is True:
	for char in string.ascii_lowercase:
		if ord(char) + shiftingKey > ord('z'):
		    print factName + '(' + char + ', ' + chr(ord(char) + shiftingKey - 26) + ').'
		else:
		    print factName + '(' + char + ', ' + chr(ord(char) + shiftingKey) + ').'

#upper chars:
if factUpper is True:
	for char in string.ascii_uppercase:
		if ord(char) + shiftingKey > ord('Z'):
		    print factName + '(' + char + ', ' + chr(ord(char) + shiftingKey - 26) + ').'
		else:
		    print factName + '(' + char + ', ' + chr(ord(char) + shiftingKey) + ').'
#digits:
if factDigits is True:
	for digit in range(10):
	    print factName + '(' + str(digit) + ', ' + str((digit + shiftingKey) % 9) + ').'


print('shift(., *).\nshift(*,.).')


# END BUILD THE FACTS BASE.. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


print('\n')


# START BUILD BASE FUNCTIONALITY.. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


# >>> 1 CHAR/DIGIT <<<<<<<<<<<<<<<<<<

#encrypt 1 char or digit:
print(encryptPredicateName + 'Char(X):- ' + factName + '(X,Y), write(Y).')

#decrypt 1 char or digit:
print(decryptPredicateName + 'Char(X):- ' + factName + '(Y,X), write(Y).')

#print both guesses of 1 char or digit:
print(bothPredicateName + 'Char(X):- shift(X,Y), shift(Z,X), write(\"maybe: \"), write(Y), '+
'write(\"\\nOR\\nmaybe: \"), write(Z), write(\'\\n=========\\n\').')


print('\n')


# >>>    STRINGS   <<<<<<<<<<<<<<<<<<

print('numToCharEnc(Number, Character) :- name(Character, [Number]), hideChar(Character).')
print('numToCharDec(Number, Character) :- name(Character, [Number]), showChar(Character).')

#encrypt string:
print(encryptPredicateName + 'String(String) :- name(String, Xs), maplist( numToCharEnc, Xs, _Characters ).')

#decrypt string:
print(decryptPredicateName + 'String(String) :- name(String, Xs), maplist( numToCharDec, Xs, _Characters ).')

#print both guesses of string:
print(bothPredicateName + 'String(String) :- write(\"maybe: \"), hideString(String), write(\"\\nOR\\nmaybe: \"),'+
' showString(String), write(\'\\n=========\\n\').')

# END BUILD BASE FUNCTIONALITY.. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


print('\n')



# START BUILD EXTRA FUNCTIONALITY.. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


#Read from file
print('readFile :-')
print('open(\'' + inputFileName + '\', read, Str), read_file(Str,Lines), close(Str), write(Lines), nl.')
print('read_file(Stream,[]) :- at_end_of_stream(Stream).')
print('read_file(Stream,[X|L]) :- \+ at_end_of_stream(Stream), read(Stream,X), write(X), write(\' : \'),'+
' write(\'\\n\'), ' + bothPredicateName + 'String(X), write(\'\\n\'), read_file(Stream,L).')

print('\n')

print('walk(X, Z, _ORG):- shift(X,Z).\nwalk(X, Z, _ORG):- _ORG \= X -> shift(X,Y), walk(Y, Z, _ORG).')


# END BUILD EXTRA FUNCTIONALITY.. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


print('\n')

examples/prologCode.pl

shift(a, d).
shift(b, e).
shift(c, f).
shift(d, g).
shift(e, h).
shift(f, i).
shift(g, j).
shift(h, k).
shift(i, l).
shift(j, m).
shift(k, n).
shift(l, o).
shift(m, p).
shift(n, q).
shift(o, r).
shift(p, s).
shift(q, t).
shift(r, u).
shift(s, v).
shift(t, w).
shift(u, x).
shift(v, y).
shift(w, z).
shift(x, a).
shift(y, b).
shift(z, c).
shift(0, 3).
shift(1, 4).
shift(2, 5).
shift(3, 6).
shift(4, 7).
shift(5, 8).
shift(6, 0).
shift(7, 1).
shift(8, 2).
shift(9, 3).
shift(., *).
shift(*,.).


hideChar(X):- shift(X,Y), write(Y).
showChar(X):- shift(Y,X), write(Y).
guessChar(X):- shift(X,Y), shift(Z,X), write("maybe: "), write(Y), write("\nOR\nmaybe: "), write(Z), write('\n=========\n').


numToCharEnc(Number, Character) :- name(Character, [Number]), hideChar(Character).
numToCharDec(Number, Character) :- name(Character, [Number]), showChar(Character).
hideString(String) :- name(String, Xs), maplist( numToCharEnc, Xs, _Characters ).
showString(String) :- name(String, Xs), maplist( numToCharDec, Xs, _Characters ).
guessString(String) :- write("maybe: "), hideString(String), write("\nOR\nmaybe: "), showString(String), write('\n=========\n').


readFile :-
open('input.txt', read, Str), read_file(Str,Lines), close(Str), write(Lines), nl.
read_file(Stream,[]) :- at_end_of_stream(Stream).
read_file(Stream,[X|L]) :- \+ at_end_of_stream(Stream), read(Stream,X), write(X), write(' : '), write('\n'), guessString(X), write('\n'), read_file(Stream,L).


walk(X, Z, _ORG):- shift(X,Z).
walk(X, Z, _ORG):- _ORG \= X -> shift(X,Y), walk(Y, Z, _ORG).

examples/input.txt

'khaled'.
'000000'.
'a.goal'.
'without.a'.
'plan.is'.
'just.a.wish.'.
Categories
All

Smart Parking System in CLIPS

Smart Parking System Task in Clips programming language

Parking Blocks

Code:

;; @Author       Khaled
;; @Subject      4_CS_AI
;; @Proj. Desc.  {Smart Parking System} 
;;				    - Organize parking process intelligently.
;;					- Suggest nearest free position.
;;
;; @Lang.        CLIPS, BASH
;; @Env.         GUI v6.3 win | CLI v6.24 debian
;; @File         @Name "app.clp" | @Created 19-nov-2018
;; @Performance  Greedy algo. | linear O(N) | N ~= positions 
;; 
;; _________________run info___________________________
;; CLIPS> (clear) 
;; CLIPS> (load C:\Users\YOUR_PATH_DIR\app.clp)
;; CLIPS> (run)
;;###########################################################



;; ~~~~  START STYLE FUNCTIONS  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(deffunction print-lines (?howMany)
	(while (> ?howMany 0) do (printout t crlf) (bind ?howMany (- ?howMany 1)))
)

(deffunction print-spaces (?howMany)
	(while (> ?howMany 0) do (printout t " ") (bind ?howMany (- ?howMany 1)))
)
;; ~~~~  END STYLE FUNCTIONS  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~





;; ~~~~  START GLOBAL VARS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(defglobal 
	?*booked*  		   = (create$ )
	?*enterAnswers*    = (create$ 1 e enter)
	?*leaveAnswers*    = (create$ 2 l leave)
	?*welcomeAnswers*  = (create$ ?*enterAnswers* ?*leaveAnswers*)
	?*exitAnswers*     = (create$ exit end out pause halt -1 3)
)
;; ~~~~  END GLOBAL VARS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




;; ~~~~  START MY CORE FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

;; Constant O(1)
(deffunction wait-any-key()
	(printout t "press any key to continue! ")
	(bind ?wait (read))
)


;; Constant O(1)
(deffunction is-valid-position(?pos)
	(return (and (>= ?pos 1) (<= ?pos 20)))
)

;; Linear O(N)
(deffunction removeBooked (?pos)
	(bind ?start 1)
	(bind ?end 20)
	(bind ?tmpBooked (create$))
	(while (<= ?start ?end)
		(if (and (<> ?start ?pos) (member$ ?start ?*booked*))
			then
				(bind ?tmpBooked (insert$ ?tmpBooked 1 ?start))
		)
		(bind ?start (+ ?start 1))
	)
	(bind ?*booked* ?tmpBooked)
	(return 0)
)

;; Constant O(1)
(deffunction getDistanceOfIndex(?idx)

	;; Positions 2 Lines:
	;;  GA  [1  : 10]
	;;  TE  [20 : 11]
	
	;; Algorithm Pseudocode:-
	;;''''''''''''''''''''''
	;; if     distance <= 10  =:  distance_to_gate = idx[1:10]
	;; elseif distance <= 20  =:  distance_to_gate = 20 - idx[11:20] + 1
	
	(if (and (>= ?idx 1) (<= ?idx 10))
		then
			(return ?idx)
		else
			(if (and (>= ?idx 11) (<= ?idx 20))
				then
					(return (+ (- 20 ?idx) 1))
			)
	)
	(return -1)
)


;; Linear O(N)
(deffunction getNearestEmptyPosition ()
	(bind ?start 1)
	(bind ?end 20)
	(bind ?bestIdx 1)
	(bind ?mi 11)  ;; max possible is 10
	
	(while (<= ?start ?end)
		(if (not (member$ ?start ?*booked*))
			then
				(bind ?disOfIdx  (getDistanceOfIndex ?start))
				(if (< ?disOfIdx ?mi)
					then
						(bind ?mi ?disOfIdx)
						(bind ?bestIdx ?start)
				)
		)
		(bind ?start (+ ?start 1))
	)
	(return ?bestIdx)
)


;; ~~~~  START MY CORE FUNCTIONS  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




;; ~~~~  START MESSAGES  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(deffunction message-welcome()
	(print-lines 25) (print-spaces 20)
	(printout t "--=  Smart Parking System using CLIPS (AI)Project  =--")
	(print-lines 2)(print-spaces 30)(printout t "Organize parking process intelligently!")
	(print-lines 20) (printout t "Choose:") (print-lines 1)
	(printout t "1- Enter (1, e, E, Enter)")     (print-lines 1)
	(printout t "2- Leave (2, l, L, Leave)")     (print-lines 1)
	(printout t "3- Exit  (3, -1, exit, end, halt, out, pause)") (print-lines 2)(printout t "? ")
)

(deffunction message-select-position()
	(print-lines 25) (print-spaces 20)
	(printout t "There are 20 positions (2 lines)") (print-lines 3)
	(printout t "  Enter  |\\_   1  2   3   4   5   6   7   8   9  10")(print-lines 1)
	(printout t "  GATE   |/   20 19  18  17  16  15  14  13  12  11")(print-lines 2)
	(print-lines 5)
)

(deffunction message-leave-position()
	(print-lines 5) (printout t "What was your position? ")
)

(deffunction message-all-busy()
	(print-lines 5)(printout t "Sorry all positions are busy!")(print-lines 5)
)

(deffunction message-booked-position()
	(print-lines 5)(printout t "Sorry you entered booked position!")(print-lines 5)
)

(deffunction message-wrong-position()
	(print-lines 5)(printout t "Sorry you entered wrong position! (correct [1 : 20])")
	(print-lines 5)
)

(deffunction message-selected-position-empty()
	(print-lines 5)(printout t "Sorry selected position is already empty!")
	(print-lines 5)
)

(deffunction message-enter-ok(?pos)
	(print-lines 5)(printout t "Welcome ^_*")(print-lines 5)
	(printout t "Use position [" ?pos "] please!" )(print-lines 5)
)


(deffunction message-best-nearest(?pos)
	(print-lines 5)(printout t "[note] nearest empty position to gate is " ?pos)
	(print-lines 5)
)

(deffunction message-leave-ok()
	(print-lines 5)
	(printout t "Thank you *_^ for using our parking service, see you soon!")
	(print-lines 5)
)

;; ~~~~  END MESSAGES  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~






;; ~~~~ START POINT ~~~~
(defrule MAIN::__COOL_CPU__

	?f <- (initial-fact)
=>
	(retract ?f)
	(message-welcome)
	(bind ?input (read))
	
	;; Normalize the input
	(if (lexemep ?input) then (bind ?input (lowcase ?input)))  
	
	(if (or (member$ ?input ?*enterAnswers*)
			(member$ ?input ?*leaveAnswers*)
		)
		then
			(assert (ask-position))
	)
	(assert (answer-welcome ?input))
)



(defrule MAIN::ASKER-POSITION
	?f <- (ask-position)
	(answer-welcome ?ans)
=>
	(if (member$ ?ans ?*enterAnswers*)
		then
			(message-select-position)
			(message-best-nearest (getNearestEmptyPosition))
			(printout t "Choose? ")
			(assert (booking-now))
		else
			(message-leave-position)
			(assert (leave-now))
	)
	
	(assert (answer-position (read)))
	(retract ?f)
)




(defrule MAIN::BOOK
	?f <- (booking-now)
	?x <- (answer-welcome  ?welcome)
	(test (member$ ?welcome ?*enterAnswers*))
	?p <- (answer-position ?pos)
=>
	(if (and (is-valid-position ?pos) (not (member$ ?pos ?*booked*)))
		then
			(bind ?*booked* (insert$ ?*booked* 1 ?pos))
			(message-enter-ok ?pos)
		else
			(if (>= (length ?*booked*) 20)
				then
					(message-all-busy)
				else
					(if (not (is-valid-position ?pos))
						then
							(message-wrong-position)
						else
							(message-booked-position)
					)
			)
	)
	(wait-any-key)
	(retract ?f)
	(retract ?p)
	(retract ?x)
	(assert (initial-fact))
)


(defrule MAIN::LEAVE
	?f <- (leave-now)
	?x <- (answer-welcome  ?welcome)
	(test (member$ ?welcome ?*leaveAnswers*))
	?p <- (answer-position ?pos)
=>
	(if (member$ ?pos ?*booked*)
		then
			(removeBooked ?pos)
			(message-leave-ok)
		else
			(if (not (is-valid-position ?pos))
				then
					(message-wrong-position)
				else
					(message-selected-position-empty)
			)
	)
	(wait-any-key)
	(retract ?f)
	(retract ?x)
	(retract ?p)
	(assert (initial-fact))
)



 
(defrule MAIN::APP-WINDOW
	?f <- (answer-welcome ?ans)
	(test (not (member$ ?ans ?*exitAnswers*)))
=>
	(retract ?f)
	(assert (initial-fact))
)
 
(reset)
 
(run)
 
(exit)