Sunday, January 25, 2009

Clojure: Genetic Mona Lisa problem in 250 beautiful lines


Clojure is surrounded by hype these days. The word on the streets is that Clojure is the Next Big Thing. It has access to the largest library of code and it proposes a nice solution the to the concurrency problem. Lots more has been said...

But I haven't seen a lot of code.

So I set out to make a small but meaningful program in Clojure to get a sense of it's potential.

I give Clojure two thumbs up, and I think you'll do too.

The Mona Lisa Problem

The program I present tries to paint Mona Lisa with a small number of semi-transparent colored polygons. It does so by using Darwin's theory of evolution to evolve programs that draw Mona Lisa.

Here's the simplified algorithm:
1. Generate an initial population of programs
2. Take the n best programs of the current population
3. Create Children from the best programs by mating and mutating them
4. Replace the current population with the n-best and the children programs
5. Repeat from 2 until satisfied

See my more complete java version for details and don't miss Roger Alsing's seminal post.

Clojure is Lisp

Lisp code can be treated as data. That makes evolving programs painless. My Genetic Algorithm simply evolves lambdas. Running the evolved programs is a matter of calling 'eval.

The program is side-effects free(almost!). The majority of the program is functional. There are only two sources of side-effects:
1. Drawing on the canvas
2. Handling the GUI

Clojure is Java

It can be distributed and run anywhere. Clojure is compiled to Java bytecodes.

Clojure can use Java objects directly without wrappers. I was able to create a cross-platform GUI in a few lines with Swing.

Let me illustrate this by creating an object deriving from JPanel that overides the paint method to draw a green rectangle.


(def rec-panel (proxy [JPanel] []
(paint [graphics]
(doto graphics
(.setColor Color/green)
(.fillRect 0 0 10 10)))))

Parallelism

I painlessly parallelized my code because it is side-effects free. Clojure provides primitives that can parallelize functional code.

The bottleneck of the application is calculating the fitness of each individual of a population. In functional terms, it is expressed by mapping each individual to it's fitness using 'map with 'fitness function as it's first argument and the population as it's second argument.

Clojure provides the 'pmap function to make that mapping parallel. It divides the work between worker threads and it uses as many of them as you have CPU cores.

Thus, writing functionaly allowed me to parallelize my code by adding one 'p' character.

See clojure.parallel.

Performance

Performance wasn't a concern when I wrote the application. I tried to keep it simple. After all, that is the purpose of using a high-level language.

Surprisingly, the fitness function(the bottleneck) runs faster in Clojure than in Java. Unfortunately I don't have time to dig into this now.

Here's a graph comparing the run time the fitness function in Java and Clojure. The measure is the average of 25 samples of 100 runs of the fitness function in each language.



Here's the benchmark for reference.

A deal breaker

Lambdas are not garbage collected.

Yes. That means lambdas can be the cause of memory leaks.

As described by Charles Nutter, each lambda in Clojure is an anonymous class in Java. The problem is that classes are never garbage collected. They reside in a special place called the PermGen.

No need to say, my program quickly fills up the PermGen.

The only solution for now is to extend the PermGen.

java -XX:MaxPermSize=1024m -cp clojure.jar clojure.lang.Repl mona-clojure.clj

I don't think this is a problem for most applications though.

EDIT: As of r1232, lambdas created in eval can be GCed. Thanks to Christophe Grand for pointing it out.

The Mona Lisa Challenge

Let's see what your favorite language can do. The challenge is to write a small program that solves the Mona Lisa problem using Genetic Programming.

Show us some code!

Some of the languages I'd like to see are Haskell, Factor, Potion, Ioke, Erlang among lots of others.

Don't forget to leave a link in the comment section of this post.

The code

Here's the github repository.

Please read the source code with syntax highlighting on github.

The following is the full code listing for the impatient only.


(import
'(java.awt Graphics Graphics2D Color Polygon)
'(java.awt.image BufferedImage PixelGrabber)
'(java.io File)
'(javax.imageio ImageIO)
'(javax.swing JFrame JPanel JFileChooser))

; ---------------------------------------------------------------------
; This section defines the building blocks of the genetic programs.

; color :: Integer -> Integer -> Integer -> Integer -> Color
(defn color [red blue green alpha] {:type :Color :red red :blue blue :green green :alpha alpha})

; point :: Integer -> Integer -> Point
(defn point [x y] {:type :Point :x x :y y})

; polygon :: Color -> [Point] -> Polygon
(defn polygon [color points] {:type :Polygon :color color :points points})

; draw-polygon :: Graphics -> Polygon -> Nothing
(defn draw-polygon [graphics polygon]
(doto graphics
(.setColor (new Color (:red (:color polygon))
(:blue (:color polygon))
(:green (:color polygon))
(:alpha (:color polygon))))
(.fillPolygon (let [jpolygon (new Polygon)]
(doseq [p (:points polygon)] (. jpolygon (addPoint (:x p) (:y p))))
jpolygon)))
nil)

; ----------------------------------------------------------------------
; This sections defines helper functions.

; random-double :: Double
(defn random-double
"Returns a double between -1.0 and 1.0."
[]
(- (* 2 (rand)) 1))

; remove-item :: Sequence -> Integer -> Sequence
(defn remove-item
"Returns a sequence without the n-th item of s."
[s n]
(cond
(vector? s) (into (subvec s 0 n)
(subvec s (min (+ n 1) (count s)) (count s)))
(list? s) (concat (take n s)
(drop (inc n) s))))

; replace-item :: [a] -> Integer -> a -> [a]
(defn replace-item
"Returns a list with the n-th item of l replaced by v."
[l n v]
(concat (take n l) (list v) (drop (inc n) l)))

; grab-pixels :: BufferedImage -> [Integer]
(defn grab-pixels
"Returns an array containing the pixel values of image."
[image]
(let [w (. image (getWidth))
h (. image (getHeight))
pixels (make-array (. Integer TYPE) (* w h))]
(doto (new PixelGrabber image 0 0 w h pixels 0 w)
(.grabPixels))
pixels))

; ----------------------------------------------------------------------
; This sections define the primitives of the genetic algorithm.

; program :: S-Expression -> Maybe Integer -> Maybe BufferedImage -> Program
(defn program [code fitness image] {:type :Program :code code :fitness fitness :image image})

; initial-program :: Program
(def initial-program (program '(fn [graphics]) nil nil))

; program-header :: Program -> S-Expression
(defn program-header [p] (take 2 (:code p)))

; program-expressions :: Program -> S-Expression
(defn program-expressions [p] (drop (count (program-header p)) (:code p)))

; mutate :: a -> Map -> a
(defmulti mutate :type)

; mutate :: Color -> Map -> Color
(defmethod mutate :Color [c settings]
(let [dr (int (* (:red c) (random-double)))
dg (int (* (:green c) (random-double)))
db (int (* (:blue c) (random-double)))
da (int (* (:alpha c) (random-double)))]
(assoc c :red (max (min (- (:red c) dr) 255) 0)
:green (max (min (- (:green c) dg) 255) 0)
:blue (max (min (- (:blue c) db) 255) 0)
:alpha (max (min (- (:alpha c) da) 255) 0))))

; mutate :: Point -> Map -> Point
(defmethod mutate :Point [p settings]
(let [dx (int (* (:x p) (random-double)))
dy (int (* (:y p) (random-double)))]
(assoc p :x (max (min (- (:x p) dx) (:image-width settings)) 0)
:y (max (min (- (:y p) dy) (:image-height settings)) 0))))

; mutate :: Polygon -> Map -> Polygon
(defmethod mutate :Polygon [p settings]
; mutate-point :: Polygon -> Map -> Polygon
(defn mutate-point [p settings]
(let [n (rand-int (count (:points p)))]
(update-in p [:points n] (fn [point] (mutate point settings)))))

; mutate-color :: Polygon -> Map -> Polygon
(defn mutate-color [p settings] (assoc p :color (mutate (:color p) settings)))

(let [roulette (rand-int 2)]
(cond
(= 0 roulette) (mutate-point p settings)
(= 1 roulette) (mutate-color p settings))))

; mutate :: Program -> Map -> Program
(defmethod mutate :Program [p settings]
; add-polygon :: Program -> Map -> Program
(defn add-polygon [p settings]
(assoc p :code
(concat (:code p)
[(list 'draw-polygon
(first (nth (:code initial-program) 1))
(polygon
(color (rand-int 255) (rand-int 255) (rand-int 255) (rand-int 255))
(vec (map
(fn [n]
(point
(rand-int (:image-width settings))
(rand-int (:image-height settings))))
(range 5)))))])
:fitness nil :image nil))

; remove-polygon :: Program -> Map -> Program
(defn remove-polygon [p settings]
(let [n (rand-int (count (program-expressions p)))]
(assoc p :code (concat (program-header p)
(remove-item (program-expressions p) n))
:fitness nil :image nil)))

; mutate-polygon :: Program -> Map -> Program
(defn mutate-polygon [p settings]
(let [expressions (program-expressions p)
n (rand-int (count expressions))
target (nth expressions n)]
(assoc p :code
(concat (program-header p)
(replace-item expressions
n
(list (nth target 0)
(nth target 1)
(mutate (nth target 2) settings))))
:fitness nil :image nil)))

(let [polygon-count (count (program-expressions p))
roulette (cond
(empty? (program-expressions p)) 4
(>= polygon-count (:max-polygons settings)) (rand-int 4)
:else (rand-int 5))]
(cond
(> 3 roulette) (mutate-polygon p settings)
(= 3 roulette) (remove-polygon p settings)
(= 4 roulette) (add-polygon p settings))))

; fitness :: Program -> Map -> Program
(defn fitness [individual settings]
(if (:fitness individual)
individual
(let [gen-image (new BufferedImage (:image-width settings)
(:image-height settings)
BufferedImage/TYPE_INT_ARGB)
src-pixels (:source-pixels settings)]
(apply (eval (:code individual)) [(. gen-image (createGraphics))])
(def gen-pixels (grab-pixels gen-image))
(loop [i (int 0)
lms (int 0)]
(if (< i (alength gen-pixels))
(let [src-color (new Color (aget src-pixels i))
gen-color (new Color (aget gen-pixels i))
dr (- (. src-color (getRed)) (. gen-color (getRed)))
dg (- (. src-color (getGreen)) (. gen-color (getGreen)))
db (- (. src-color (getBlue)) (. gen-color (getBlue)))]
(recur (unchecked-inc i) (int (+ lms (* dr dr) (* dg dg) (* db db )))))
(assoc individual :fitness lms :image gen-image))))))

; select :: [Program] -> Map -> [Program]
(defn select [individuals settings]
(take (:select-rate settings)
(sort-by :fitness
(pmap (fn [i] (fitness i settings))
individuals))))

; evolve :: Map -> Nothing
(defn evolve [settings]
(loop [i 0
population (list initial-program)]
(let [fittest (select population settings)
newborns (map (fn [i] (mutate i settings)) fittest)]
((:new-generation-callback settings (fn [a b])) i fittest)
(when-not (= (first population) (first fittest))
((:new-fittest-callback settings (fn [a b])) i fittest))
(recur (inc i) (concat fittest newborns)))))

; ----------------------------------------------------------------------
; This sections defines the graphical interface.

; main :: Nothing
(defn main []
(def file-chooser (new JFileChooser))
(doto file-chooser
(.setCurrentDirectory (new File "."))
(.showOpenDialog nil))

(let [jframe (new JFrame "Fittest Program")
fittest (atom (list initial-program))
image (ImageIO/read (. file-chooser (getSelectedFile)))
settings {:image-width (. image (getWidth))
:image-height (. image (getHeight))
:source-pixels (grab-pixels image)
:select-rate 1 :max-polygons 50
:new-fittest-callback (fn [i f]
(swap! fittest (fn [o n] n) f)
(. jframe (repaint)))}]
(doto jframe
(.setSize (. image (getWidth)) (. image (getHeight)))
(.add (proxy [JPanel] []
(paint [g]
(doto g
(.setColor Color/white)
(.fillRect 0 0 (. image (getWidth)) (. image (getHeight)))
(.drawImage (:image (first @fittest)) nil 0 0)))))
(.setVisible true))
(evolve settings)))

(main)

125 comments:

Christophe Grand said...

As of r1232, lambdas created in eval can be GCed.

Harold Fowler said...

Fascinating stuff! I think you might just be onto something!

RT
www.total-privacy.us.tc

The Great Hive said...

Maybe you should credit the guy who did his last month in Javascript, since you clearly took your lead from him.

Daniel said...

Interesting code, but there should be more information.

www.reviewstash.com

For the latest in tech news!

Yann N. Dauphin said...

@Daniel. Thanks. What else would you like to know?

@The Great Hive. I did see his version. Anyway, I plan to link to him in a follow-up post commenting on all known implentations of this problem.

Emeka said...

Great job son!

Lauri said...

I think you're missing the second argument to max for :blue and :alpha in (mutate).

Also, if any of the colours or coordinates hit 0, they'll be stuck there, because the mutation is based on multiplication. Maybe this does not matter, i.e. those individuals will be eventually culled from the population?

-- Lauri

Yann N. Dauphin said...

@Lauri. Thanks, I corrected the mistakes.

I'm still unsure about what to do about the colors/coordinates hitting 0. I'll perform some tests to find out.

Yann.

Xetas said...

I wonder is there less ugly way to express following line:

(assoc p :points (assoc (:points p) n (mutate (get (:points p) n) settings)))

which actually means:

mutate(p.points[n], settings)

Xetas said...

Found answer to my own question:

(update-in p [:points n] #(mutate %1 settings))

Yann N. Dauphin said...

@Xetas. Great find. I'll update my code when I get home.

Anonymous said...

Hello Yann,

I liked your solution with clojure, I think clojure is definitely cool and worth learning.

I wrote a Haskell application for the Mona Lisa problem. It is a bit longer than 250 lines (and probably not as beautiful). I kept close to the original implementation (C#). There are two different branches, one of them uses Data Parallel Haskell for the fitness-/error- function. This is a vectorisation approach (about 27 percent speedup).

More details about it in my blog:
http://e7ektro.wordpress.com/2009/01/31/hevolisa/

Download Cabal package from Hackage:
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hevolisa-0.0
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hevolisa-dph-0.0

Git repository on github:
http://github.com/dneun/hevolisa/tree/master

The implementation is based on Gtk2Hs.

Yann N. Dauphin said...

@e7ektro

I was eager to see a solution with Haskell. Yours is great.

It gives a clear sense of what Haskell is. I like that everything is a combination of functions. Like the implementation of the error function:

error :: [Integer] -> [Integer] -> Integer
error c1 c2 = sum $ zipWith (\x y -> (x - y)^2) c1 c2

Short and Sweet.

Yann.

Andrew said...

I'm playing around with your code and saw that you said the evals can be GCed now, but I'm still seeing a huge memory footprint. Is there new code that needs to be added to do the GC? I'm new to Clojure, so maybe I'm missing something.

Yann N. Dauphin said...

@Andrew

The fix for the GC problem hasn't been officially released yet. That's probably why you don't see any difference.

You can get the fix from the lastest SVN revision:
svn checkout http://clojure.googlecode.com/svn/trunk/ clojure-read-only

Andrew said...

Ah, thanks. :)

daniel john said...

I like that everything is a combination of functions. Thanks for sharing.
Term Paper

Lanthanum said...
This comment has been removed by a blog administrator.
Maurits said...

Any idea why this is so much slower when using Clojure 1.2?

Maya Angelou said...
This comment has been removed by a blog administrator.
Jessica Amy said...
This comment has been removed by a blog administrator.
Priya Kannan said...

Great post! I am see the great contents and step by step read really nice information.I am gather this concepts and more information. It's helpful for me my friend. Also great blog here with all of the valuable information you have.
PHP Training in Chennai

Freddie King said...

Thank you for taking the time and sharing this information with us. It was indeed very helpful and insightful while being straight forward and to the point.
mcdonalds.gutscheine | startlr.com | saludlimpia.com

Sean Parker said...

There might be some tool or framework that simplifies your work?
cheap manchester airport parking deals

Nila shri said...

Thank you for your sharing pretty Information.

Data Science Training in Chennai

Data science training in bangalore

Data science training in kalyan nagar

Data science training in kalyan nagar

online Data science training

Data science training in pune

Data science training in Bangalore

Unknown said...

myTectra a global learning solutions company helps transform people and organization to gain real, lasting benefits.Join Today.Ready to Unlock your Learning Potential ! Read More....

Unknown said...

myTectra offers corporate training services in Bangalore for range of courses on various domain including Information Technology, Digital Marketing and Business courses like Financial Accounting, Human Resource Management, Health and Safety, Soft Skill Development, Quality & Auditing, Food Safety & Hygiene. myTectra is one of the leading corporate training companies in bangalore offers training on more than 500+ courses
corporate training in bangalore
top 10 corporate training companies in india
corporate training
corporate training companies
along these we are going to help the professionals and students to crack their interview with interview questions and answers look a head into sites you might be like....
spring interview questions
jsp interview questions

Eminent It Info said...

I have read your blog its very attractive and impressive. I like it your blog.
data science training in bangalore | AWS training in Marathahalli Bangalore | Microsoft Azure training in Marathahalli Bangalore

amsa leka said...

Thanks for such a great article here. I was searching for something like this for quite a long time and at last I’ve found it on your blog. It was definitely interesting for me to read about their market situation nowadays. Well written article.future of android development 2018 | android device manager location history

Roja Priya said...

Thank you for sharing your article. Great efforts put it to find the list of articles which is very useful to know, Definitely will share the same to other forums.
Data Science Training in chennai at Credo Systemz | data science course fees in chennai | data science course in chennai quora | data science with python training in chennai

Anbarasan14 said...

Nice blog!! I really got to know many new tips by reading your blog. Thank you so much for a detailed information! It is very helpful to me. Kindly continue the work.

TOEFL Class in Chennai Porur
TOEFL Training in Iyyappanthangal
TOEFL Training in DLF
TOEFL classes in St.Thomas Mount
TOEFL Coaching in Ramapuram
TOEFL Classes in Mugalivakkam
TOEFL Training in Kolapakkam

Ananya Krishnan said...

Good job in presenting the correct content with the clear explanation. The content looks real with valid information. Good Work

DevOps is currently a popular model currently organizations all over the world moving towards to it. Your post gave a clear idea about knowing the DevOps model and its importance.

Good to learn about DevOps at this time.


devops training in chennai | devops training in chennai with placement | devops training in chennai omr | devops training in velachery | devops training in chennai tambaram | devops institutes in chennai | devops certification in chennai | trending technologies list 2018

Aruna Ram said...

It was so nice and very used for develop my knowledge skills. Thanks for your powerful post. I want more updates from your blog....
Data Science Training in Bangalore
Best Data Science Courses in Bangalore
Data Science Course in Annanagar
Data Science Training in Chennai Adyar
Data Science Training in Tnagar
Data Science Training in Chennai Velachery

Rithi Rawat said...

Thankyou for providing the information, I am looking forward for more number of updates from you thank you

machine learning with python course in chennai
machine learning course in chennai
best training insitute for machine learning
Android training in Chennai
PMP training in chennai

jyothi kits said...

This post is much helpful for us.
informatica mdm training
informatica training

jyothi kits said...

I feel happy to find your post.
Android Training
Appium Training

Durai Raj said...

The data which you have shared is very much useful to us... thanks for it!!!
big data courses in bangalore
hadoop training institutes in bangalore
Hadoop Training in Bangalore
Data Science Courses in Bangalore
CCNA Course in Madurai
Digital Marketing Training in Coimbatore
Digital Marketing Course in Coimbatore

Praylin S said...

Thank you for this wonderful post! I'm learning a lot from here. Keep sharing and keep us updated.
Microsoft Dynamics CRM Training in Chennai
Microsoft Dynamics Training in Chennai
Tally Course in Chennai
Tally Classes in Chennai
Embedded System Course Chennai
Embedded Training in Chennai
Microsoft Dynamics CRM Training in Adyar
Microsoft Dynamics CRM Training in Porur

Shiva Shakthi said...

Awesome post!!! Thanks a lot for sharing with us....
Spring Training in Chennai
Spring and Hibernate Training in Chennai
Hibernate Training in Chennai
Struts Training in Chennai
Spring Training in Anna Nagar
Spring Training in Adyar

Singh said...

Wow!! Really a nice Article. Thank you so much for your efforts. Definitely, it will be helpful for others. I would like to follow your blog..Artificial Intelligence Training in Bangalore. Keep sharing your information regularly for my future reference. Thanks Again.

harish sharma said...

whatsapp group links 2019

sathya shri said...

Awesome article. It is so detailed and well formatted that i enjoyed reading it as well as get some new information too.

DevOps Training in Bangalore

DevOps Training in Pune

DevOps Online Training

Dale Morris said...

Click here |Norton Customer Service
Click here |Mcafee Customer Service
Click here |Phone number for Malwarebytes
Click here |Hp printer support number
Click here |Canon printer support online

Shiva Shakthi said...

More Informative Blog!!! Thanks for sharing with us...
devops training in bangalore
devops course in bangalore
devops certification in bangalore
Java Training in Bangalore
Python Training in Bangalore
IELTS Coaching in Madurai
IELTS Coaching in Coimbatore

Java Training in Coimbatore

franklinraj said...

Thank you for excellent article.

Please refer below if you are looking for best project center in coimbatore

soft skill training in coimbatore
final year projects in coimbatore
Spoken English Training in coimbatore
final year projects for CSE in coimbatore
final year projects for IT in coimbatore
final year projects for ECE in coimbatore
final year projects for EEE in coimbatore
final year projects for Mechanical in coimbatore
final year projects for Instrumentation in coimbatore

VRITPROFESSIONALS said...

Nice post. Thanks for sharing! I want people to know just how good this information is in your article. It’s interesting content and Great work.
Thanks & Regards,
VRIT Professionals,
No.1 Leading Web Designing Training Institute In Chennai.

And also those who are looking for
Web Designing Training Institute in Chennai
SEO Training Institute in Chennai
Photoshop Training Institute in Chennai
PHP & Mysql Training Institute in Chennai
Android Training Institute in Chennai

Lucky Patcher (LP) said...

original lucky patcher download

Groups For said...

Your post or article upon monaliza is great and also like monaliza picture and its maker like daminchi.
Join our latest whatsapp related stuff.
Latest Active Whatsapp Groups Links For 2019
Girls WhatsApp Group Link
Whatsapp Status 2019

Exotic Irfan said...

https://www.cutehindi.com/2019/02/best-names-for-pubg.html

Shady Marshall said...

Java is very powerful language.

Cheap Gatwick Parking

sandhya kits said...

Great, thanks for sharing this blog.Really looking forward to read more. Keep writing
Oracle SOA Online Training

Oracle Weblogic Online Training

OSB Online Training

OTM Online Training

PHP Online Training

Power BI Online Training

Python Online Training

QlikView Online Training

Quality Stage Online Training

Arun Kumar said...

Hey Nice Blog!! Thanks For Sharing!!!Wonderful blog & good post.Its really helpful for me, waiting for a more new post. Keep Blogging!
SEO company in coimbatore
SEO company
web design company in coimbatore

Lili Diaz said...

girls whatsapp number
whatsapp groups
telegram groups links
pubg names
dojo me

meenati said...

It's a Very informative blog and useful article thank you for sharing with us, keep posting learn more about BI Tools Thanks for sharing valuable information. Your blogs were helpful to tableau learners. I request to update the blog through step-by-step. Also, find Technology news at
Tableau Training

Android Online Training

Data Science Certification

Dot net Training in bangalore

Blog.

Creators Seo Master said...

super your blog
andaman tour packages
andaman holiday packages
web development company in chennai
Math word problem solver
laptop service center in chennai
Austin Homes for Sale

Vicky Ram said...

It is a great post. Keep sharing such kind of useful information.

karnatakapucresult
Article submission sites

prmrtjs said...

Thank you for share Far cry primal

prakash gohel said...

Thank you for this great article i learn a lot from your article keep it up.
attitude status in hindi
Life status in hindi
Love Status in hindi

Teena bhabhi said...

many peoples want to join random whatsapp groups . as per your demand we are ready to serve you whatsapp group links . On this website you can join unlimited groups . click and get unlimited whatsapp group links

Mafia said...

whatsapp status

fuck yeah said...

HP Printer Technical Support Number
HP Printer Technical Support Number
HP Printer Technical Support Phone Number
HP Printer Technical Support
HP Printer Tech Support Number
HP Printer Tech Support
HP Technical Support
HP Tech Support
HP Printer Support Phone Number
HP Printer Support Number
HP Printer Support Phone Number
HP Printer Customer Support Number
HP Printer Helpline Number
HP Printer Support
HP Support
HP Printer Customer Number
HP Printer Customer service Number
HP Printer Customer toll-free Number
HP Printer Customer toll-free Number
HP Printer Helpline Number
HP Printer Helpline Number
HP Printer Helpline
HP Printer Toll Free Number
HP Printer Toll free

fuck yeah said...

HP Printer Technical Support Number
HP Printer Technical Support Number
HP Printer Technical Support Phone Number
HP Printer Technical Support
HP Printer Tech Support Number
HP Printer Tech Support
HP Technical Support
HP Tech Support
HP Printer Support Phone Number
HP Printer Support Number
HP Printer Support Phone Number
HP Printer Customer Support Number
HP Printer Helpline Number
HP Printer Support
HP Support
HP Printer Customer Number
HP Printer Customer service Number
HP Printer Customer toll-free Number
HP Printer Customer toll-free Number
HP Printer Helpline Number
HP Printer Helpline Number
HP Printer Helpline
HP Printer Toll Free Number
HP Printer Toll free

Anjali Siva said...

Great blog, I was searching this for a while. Do post more like this.
Data Science Course in Chennai
Data Analytics Courses in Chennai
Data Analyst Course in Chennai
R Programming Training in Chennai
Data Analytics Training in Chennai
Machine Learning Course in Chennai
Machine Learning Training in Velachery
Data Science Training in Chennai

Jhon Micle said...

amazing blog layout! How long have you been blogging for? Get Free Girls WhatsApp Numbers Latest 2019 you make blogging look easy.

QuickBooks Customer Support Number said...

In September 2005, QuickBooks acquired 74% share associated with market in the us. A June 19, 2008 Intuit Press Announcement said that at the time of March 2008, QuickBooks Customer Support Number’ share of retail units in the industry accounting group touched 94.2 percent, according to NPD Group. In addition says more than 50,000 accountants, CPAs and self-regulating business advisers are people into the QuickBooks ProAdvisor program.

Sana Khan said...

kinemaster mod apk
uptodownapk
Ptcl Smart Tv App
tinder boost hack APK
Bypass Google Account

Kesari said...

HAPPY BIRTHDAY IMAGES FOR BROTHER WITH QUOTES

HOW TO DOWNLOAD AADHAR CARD ONLINE


SPOTIFY PREMIUM MOD APK DOWNLOAD

Internationalroamingtech.com

vyshu kits2019 said...

Awesome article. It is so detailed and well formatted that i enjoyed reading it as well as get some new information too.

SAP Hybris Interview Questions and Answers


SAP MM Interview Questions and Answers


SAP PP Interview Questions and Answers


SAP QM Interview Questions and Answers


SAP SD Interview Questions and Answers


SAP Security Interview Questions and Answers


SAP UI5 Interview Questions and Answers


SAP WM Interview Questions and Answers

LuckyP said...

free download best app lucky patcher

LuckyP said...

free download best app lucky patcher

Aman CSE said...


One of the best content i have found on internet for Data Science training in Chennai .Every point for Data Science training in Chennai is explained in so detail,So its very easy to catch the content for Data Science training in Chennai .keep sharing more contents for Trending Technologies and also updating this content for Data Science and keep helping others.
Cheers !
Thanks and regards ,
DevOps course in Velachery
DevOps course in chennai
Best DevOps course in chennai
Top DevOps institute in chennai

Unknown said...

Actinlife

Avi said...

Nice Article…
Really appreciate your work
Birthday Wishes for Girlfriend

Aayush Modi said...

http://npcontemplation.blogspot.com/2009/01/clojure-genetic-mona-lisa-problem-in.html

rocky said...

Actinlife

ShivSai App Developer said...

"Visit PicsArt happy birthday background banner Marathi बर्थडे बैनर बैकग्राउंड"

Unknown said...

vpn master premium apk for free

newmobilelaunches said...

cashify coupon codes

Admin said...

valuable information Health Tips Telugu

anusha said...


data science training in chennai Data Science Training in Chennai with real time projects. We are Best Data Science Training Institute in Chennai. Our Data Science training courses are taught by Experts.

Unknown said...

I would like to thank you for the efforts you have made in writing this article . I am hoping the same best work from you in the future as well.

ExcelR Solutions 16 hours ago said...

Really Amazing Article.Keep up the good work.
data science course

DirectSelling said...

Despite Boruto's physical designs being similar to Naruto when he was young, their personalities are developed differently. Boruto's relationship with his father reflects Kishimoto's relationship with his children. In the Japanese version, Boruto is voiced by Kokoro Kikuchi in The Last: Naruto the Movie and by Yūko Sanpei in all subsequent appearances. Sanpei enjoyed doing the work of Boruto's acting, finding him endearing. In the English version, he is voiced by Amanda C. Miller.

http://borutofillerlist.online

Basudev said...

Nice tutorial

Modded Android Apps

Mathew said...

There is occasions as soon as you might face some type of delay in reaching us, let’s say during the time of filing taxes since there is a lot of hush-hush then. We assure you that individuals will revert to your account in less time and work out us accessible to you at QuickBooks Support Phone Number.

kevin32 said...

We all know that for the annoying issues in QuickBooks Enterprise Support Phone Number software, you will need a smart companion who is able to enable you to eradicate the errors instantly.

QuickBooks Enterprise Support Number said...

For such type of information, be always in contact with us through our blogs. To find the reliable supply of help to create customer checklist in QB desktop, QuickBooks online and intuit online payroll? Our QuickBooks Payroll Support Phone Number might help you better.

accounting said...

QuickBooks Support Phone Number has a great deal to offer to its customers so that you can manage every trouble that obstructs your projects. There are tons many errors in QuickBooks such as difficulty in installing this software, problem in upgrading the application into the newer version so that you can avail the most up-to-date QuickBooks features, trouble in generating advanced reports, difficulty with opening company file in multi-user mode and so on and so forth.

Aaditya said...

Easily, the article is actually the best topic. Looking forward to your next post. Thanks

Data Science Courses

steffan said...

Might you run a company? Would it be too much to deal with all? You need a hand for support. QuickBooks Payroll Tech Support is a remedy. If you want to accomplish that through QuickBooks, you obtain several advantages. Today, payroll running is currently complex. You might need advanced software. There must be a premier mix solution.

lampungservice.com said...

http://servicehpterdekat.blogspot.com/
http://servicehpterdekat.blogspot.com/http://servicehpterdekat.blogspot.com/
iPhone
https://kursusservicehplampung.blogspot.com/
http://lampungservice.com/
http://lampungservice.com/
http://lampungservice.com/
https://cellularlampung.blogspot.com/

QuickBooks Customer Service Phone Number said...

Without taking most of your time, our team gets you rid of all unavoidable errors of this software. QuickBooks Tech Support Phone Number Would you like to Update QuickBooks Pro? We now have was able to make it simple for you at.

zaintech99 said...

Hey Nice Blog!! Thanks For Sharing!!!Wonderful blog & good post.Its really helpful for me, waiting for a more new post. Keep Blogging!https://www.excelr.com/data-analytics-certification-training-course/
https://www.excelr.com/data-science-course-training/
https://www.excelr.com/data-analytics-certification-training-course-in-bangalore/

zaintech99 said...
This comment has been removed by the author.
sripadojwar said...

thank you for the sharing the blog i have collected the stuff

https://www.excelr.com/servicenow-training-in-gurgaon

steffan said...

Quickbooks Support Phone Number serving a number of users daily , quite possible you will definitely hand up or need to watch for few years in order to connect with the Help Desk team . In accordance with statics released by the Bing & Google search insights significantly more than 50,000 people searching the net to get the Quickbooks Technical Support Phone number on a daily basis and much more than 2,000 quarries related to Quickbooks issues and errors .

QuickBooks Customer Service Phone Number said...

you'll be just a call away to your solution. Reach us at QuickBooks Tech Support Number at and experience our efficient tech support team of many your software related issues. If you're aa QuickBooks enterprise user, it is possible to reach us out immediately at our QuickBooks Support contact number . QuickBooks technical help is present at our QuickBooks tech support number dial this and gets your solution from our technical experts.

Riya Raj said...

Outstanding blog!!! Thanks for sharing with us...
IELTS Coaching in Coimbatore
IELTS Coaching Center in Coimbatore
RPA training in bangalore
Selenium Training in Bangalore
Oracle Training in Coimbatore
PHP Training in Coimbatore

Mathew said...

UNINTERRUPTED SUPPORT AT QuickBooks Support Number-QuickBooks Enterprise Support contact number team makes it possible to deal with most of the issues of QB Enterprise.

xpert said...

The QuickBooks Payroll has many awesome features that are good enough when it comes to small and middle sized business. QuickBooks Payroll also offers a dedicated accounting package which include specialized features for accountants also. You can certainly all from the QuickBooks Payroll Tech Support Number to find out more details. Let’s see many of the options that come with QuickBooks that features made the QuickBooks payroll service exremely popular.

QuickBooks Payroll Support said...

This software of QuickBooks Payroll Support Number is sold with various versions and sub versions. Online Payroll and Payroll for Desktop may be the two major versions and they're further bifurcated into sub versions. Enhanced Payroll and Full-service payroll are encompassed in Online Payroll whereas Basic, Enhanced and Assisted Payroll come under Payroll for Desktop.

raja yadav said...

itechraja.com



IndiaYojna.in




google se paise kaise kamaye

accountingwizards said...

The attributes of QuickBooks Support Phone Number amaze and but sometimes feel bad when the connection with the Quickbooks happens to be lost . It is frequent issues with the program are such as for instance: QB SYNC problem , errors within the transaction report , improper functioning of payroll system errors while doing the installation. The bond lost issue, reference to the free web, sync issue in the software as well as other kind of setting which not easily can be found & may block the whole workflow .

jameswill11 said...

The satisfaction may be high class with us. It is possible to call us in many ways. You are able to travel to our website today. It is the right time to have the best help.
visit : https://www.247supportphonenumber.com/

Admin said...

Telugu Quotes

kevin32 said...

QuickBooks Payroll Support Number is possible to fill all the state taxes forms and pay their state taxes in just a couple of clicks with assisted intuit.

kevin32 said...

E-file. QuickBooks Payroll Support Number And pay every one of the Federal and state taxes by E-pay.No Tax penalty guaranteed: If the info you provide is perhaps all correct along with your fund is sufficient then your entire taxes ought to be paid on time that might help save you from nearly every penalty.

QuickBooks Customer Service Phone Number said...

The process to put in and put up QuickBooks Suppor on Windows is just like that of Mac. The system requirements when it comes to installation process may vary slightly for both the operating system.

Durai Raj said...

Interesting Blog!!! Thanks for sharing with us....
CCNA Course in Coimbatore
CCNA Training in Coimbatore
CCNA Course in Madurai
CCNA Training in Madurai
Ethical Hacking Course in Bangalore
German Classes in Bangalore
German Classes in Madurai
Hacking Course in Coimbatore
German Classes in Coimbatore

steffan said...

Are you scratching the pinnacle and stuck together with your QuickBooks related issues, you will be just one click definately not our expert tech support team for your QuickBooks related issues. We site name, are leading tech support team provider for your entire QuickBooks related issues. Either it is day or night, we offer hassle-free tech support team for QuickBooks and its associated software in minimum possible time. Our dedicated QuickBooks Tech Support Number is available to be able to 24X7, 365 days per year to be sure comprehensive support and services at any hour. We assure you the quickest solution of many your QuickBooks software related issues.

xpert said...

However, you could face the issue with your QuickBooks software and start trying to find the answer. You ought not worries, if you should be facing trouble with your software you will be just a call away to your solution. Reach us at QuickBooks Support Phone Nummber at and experience our efficient tech support team of many your software related issues. If you are aa QuickBooks enterprise user, it is possible to reach us out immediately at our QuickBooks Support.

QuickBooks Payroll Support said...

QuickBooks Payroll Support Phone Number has made payroll management quite definitely easier for accounting professionals. There are so many individuals who are giving positive feedback when they process payroll either QB desktop and online options. In this web site, we are going to enable you to experience to make and place up the checklist for employee payment.

kevin32 said...

QuickBooks Payroll Technical Support helps you to resolve all your technical and functional problems while caring for this well known extensive, premium and end-to-end business accounting and payroll management software.

steffan said...

Here we will update you the way you can obtain QuickBooks Enterprise Support or simple recommendations for connecting QuickBooks enterprise customer support contact number. QuickBooks is financial software that will assist small enterprise, large business along with home users. This computer programs will always make life possible for many if you should be taking proper care of all financial expenses and savings. The initial Quicken software will never act as a “double-entry” accounting platform.

QuickBooks Customer Service Phone Number said...

This version of QuickBooks Payroll Tech Support Number
offers payroll and accounts management solutions for businesses of small and medium sizes. The lightweight design and simple functionality for this software helps.

john kim said...

Thumbs up guys your doing a really good job.
Data Science Course in Pune

steffan said...

Now you can get a sum of benefits with QuickBooks. Proper analyses are done first. The experts find out of the nature associated with trouble. You will definately get a complete knowledge as well. The support specialist will identify the problem. The deep real cause is likely to be found out. All the clients are extremely satisfied with us. We've got many businessmen who burn off our QuickBooks Tech Support Number. You can easily come and find the ideal service to your requirements.

Ladu Sangwan said...


Best whatsapp group names
cool whatsapp group names
Best group chat names
funny whatsapp group names
whatsapp group names list
Cute Group names

rudra singh said...

sakshi malik model
very nice article ...
great information

duaking.tk said...

agar aap vi chatey ho ki aapse vi or logo ki trah ladki pate or aapki gf bane toh aap ladki ko patane ka mantra hindi me kare

smith said...

There is the facility to file taxes for your employees electronically. QuickBooks Payroll Support Number File taxing is such a humungous task and doing it by yourself is a lot like giving out your sleep for days, specially once you know nothing about tax calculations.

Komalpreet Singh said...

Go Health Science is a best resource to get all kinds of Knowledge about Health and Science updates on Healthy Life ideas.

QuickBooks Payroll Support Phone Number said...

QuickBooks Support has almost eliminated the typical accounting process. Along with a wide range of tools and automations, it provides a wide range of industry verticals with specialized reporting formats and tools

smith said...

QuickBooks has played a very important role in redefining how you look at things now. By introducing so many versions namely Pro, Premier, Enterprise, Accountant, QuickBooks Payroll Support Telephone etc.

QuickBooks Payroll Support said...

QuickBooks Enterprise Support Phone Number users are often found in situations where they should face lots of the performance and some other errors due to various causes within their computer system.