Represent Tree using graphics in C/C++

Prerequisite: graphics.hHow to include graphics.h?

In C/C++ there is graphics.h header file which is used to create the object like line, circle, etc.

Given an array arr[] of N integers, the task is to write C++ program to create the Tree using graphics.h.

Approach: To run the program we have the include the below header file:

#include 

We will create a Tree with the help below functions:

  1. setcolor(color): This function present in graphic.h header file which is used to set the current drawing color to the new color.
  2. floodfill(pattern, color): function is used to fill an enclosed area. The current fill pattern and fill color is used to fill the area.
  3. circle(x, y, radius): The header file graphics.h contains circle() function which draws a circle with center at (x, y) and given radius.
  4. outtextxy(): The header file graphics.h contains outtextxy() function which displays the text or string at a specified point (x, y) on the screen.

#computer-graphics #trees #c #c++ #cplusplus #programming-c

What is GEEK

Buddha Community

Represent Tree using graphics in C/C++
Chloe  Butler

Chloe Butler

1667425440

Pdf2gerb: Perl Script Converts PDF Files to Gerber format

pdf2gerb

Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.


pdf2gerb_cfg.pm

#Pdf2Gerb config settings:
#Put this file in same folder/directory as pdf2gerb.pl itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)


##############################################################################################
#configurable settings:
#change values here instead of in main pfg2gerb.pl file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)}Pdf2Gerb.pl ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
(
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
#traces:
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .012,
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .025,
    .030,  #heavy-current traces; be careful with these ones!
    .040,
    .050,
    .060,
    .080,
    .100,
    .120,
);
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
{
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects
};

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
{
    CIRCLE_ADJUST_MINX => 0,
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    CIRCLE_ADJUST_MAXY => 0,
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found
};

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
{
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
};
    
#number of elements in each shape type:
use constant
{
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
};
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
our %SHAPELEN =
(
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,
);

#panelization:
#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#############################################################################################
#junk/experiment:

#use Package::Constants;
#use Exporter qw(import); #https://perldoc.perl.org/Exporter.html

#my $caller = "pdf2gerb::";

#sub cfg
#{
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;
#}

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #https://www.perlmonks.org/?node_id=1072691; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code: https://github.com/swannman/pdf2gerb

License: GPL-3.0 license

#perl 

Represent Tree using graphics in C/C++

Prerequisite: graphics.hHow to include graphics.h?

In C/C++ there is graphics.h header file which is used to create the object like line, circle, etc.

Given an array arr[] of N integers, the task is to write C++ program to create the Tree using graphics.h.

Approach: To run the program we have the include the below header file:

#include 

We will create a Tree with the help below functions:

  1. setcolor(color): This function present in graphic.h header file which is used to set the current drawing color to the new color.
  2. floodfill(pattern, color): function is used to fill an enclosed area. The current fill pattern and fill color is used to fill the area.
  3. circle(x, y, radius): The header file graphics.h contains circle() function which draws a circle with center at (x, y) and given radius.
  4. outtextxy(): The header file graphics.h contains outtextxy() function which displays the text or string at a specified point (x, y) on the screen.

#computer-graphics #trees #c #c++ #cplusplus #programming-c

Brook  Hudson

Brook Hudson

1659074160

Kashmir: A Ruby DSL That Makes Serializing and Caching Objects A Snap

Kashmir is a Ruby DSL that makes serializing and caching objects a snap.

Kashmir allows you to describe representations of Ruby objects. It will generate hashes from these Ruby objects using the representation and dependency tree that you specify.

Kashmir::ActiveRecord will also optimize and try to balance ActiveRecord queries so your application hits the database as little as possible.

Kashmir::Caching builds a dependency tree for complex object representations and caches each level of this tree separately. Kashmir will do so by creating cache views of each level as well as caching a complete tree. The caching engine is smart enough to fill holes in the cache tree with fresh data from your data store.

Combine Kashmir::Caching + Kashmir::ActiveRecord for extra awesomeness.

Example:

For example, a Person with name and age attributes:

  class Person
    include Kashmir
    
    def initialize(name, age)
      @name = name
      @age = age
    end
    
    representations do
      rep :name
      rep :age
    end
  end

could be represented as:

{ name: 'Netto Farah', age: 26 }

Representing an object is as simple as:

  1. Add include Kashmir to the target class.
  2. Whitelist all the fields you want to include in a representation.
# Add fields and methods you want to be visible to Kashmir
representations do
  rep(:name)
  rep(:age)
end
  1. Instantiate an object and #represent it.
# Pass in an array with all the fields you want included
Person.new('Netto Farah', 26).represent([:name, :age]) 
 => {:name=>"Netto Farah", :age=>"26"} 

Installation

Add this line to your application's Gemfile:

gem 'kashmir'

And then execute:

$ bundle

Usage

Kashmir is better described with examples.

Basic Representations

Describing an Object

Only whitelisted fields can be represented by Kashmir. This is done so sensitive fields (like passwords) cannot be accidentally exposed to clients.

class Recipe < OpenStruct
  include Kashmir

  representations do
    rep(:title)
    rep(:preparation_time)
  end
end

Instantiate a Recipe:

recipe = Recipe.new(title: 'Beef Stew', preparation_time: 60)

Kashmir automatically adds a #represent method to every instance of Recipe. #represent takes an Array with all the fields you want as part of your representation.

recipe.represent([:title, :preparation_time])
=> { title: 'Beef Stew', preparation_time: 60 }

Calculated Fields

You can represent any instance variable or method (basically anything that returns true for respond_to?).

class Recipe < OpenStruct
  include Kashmir

  representations do
    rep(:title)
    rep(:num_steps)
  end
  
  def num_steps
    steps.size
  end
end
Recipe.new(title: 'Beef Stew', steps: ['chop', 'cook']).represent([:title, :num_steps])
=> { title: 'Beef Stew', num_steps: 2 }

Nested Representations

You can nest Kashmir objects to represent complex relationships between your objects.

class Recipe < OpenStruct
  include Kashmir

  representations do
    rep(:title)
    rep(:chef)
  end
end

class Chef < OpenStruct
  include Kashmir

  representations do
    base([:name])
  end
end

When you create a representation, nest hashes to create nested representations.

netto = Chef.new(name: 'Netto Farah')
beef_stew = Recipe.new(title: 'Beef Stew', chef: netto)

beef_stew.represent([:title, { :chef => [ :name ] }])
=> {
  :title => "Beef Stew",
  :chef => {
    :name => 'Netto Farah'
  }
}

Not happy with this syntax? Check out Kashmir::DSL or Kashmir::InlineDSL for prettier code.

Base Representations

Are you tired of repeating the same fields over and over? You can create a base representation of your objects, so Kashmir returns basic fields automatically.

class Recipe
  include Kashmir
  
  representations do
    base [:title, :preparation_time]
    rep :num_steps
    rep :chef
  end
end

base(...) takes an array with the fields you want to return on every representation of a given class.

brisket = Recipe.new(title: 'BBQ Brisket', preparation_time: 'a long time')
brisket.represent()
=> { :title => 'BBQ Brisket', :preparation_time => 'a long time' }

Complex Representations

You can nest as many Kashmir objects as you want.

class Recipe < OpenStruct
  include Kashmir

  representations do
    base [:title]
    rep :chef
  end
end

class Chef < OpenStruct
  include Kashmir

  representations do
    base :name
    rep :restaurant
  end
end

class Restaurant < OpenStruct
  include Kashmir

  representations do
    base [:name]
    rep :rating
  end
end
bbq_joint = Restaurant.new(name: "Netto's BBQ Joint", rating: '5 Stars')
netto = Chef.new(name: 'Netto', restaurant: bbq_joint)
brisket = Recipe.new(title: 'BBQ Brisket', chef: netto)

brisket.represent([
  :chef => [
    { :restaurant => [ :rating ] }
  ]
])

=> {
  title: 'BBQ Brisket',
  chef: {
    name: 'Netto',
    restaurant: {
      name: "Netto's BBQ Joint",
      rating: '5 Stars'
    }
  }
}

Collections

Arrays of Kashmir objects work the same way as any other Kashmir representations. Kashmir will augment Array with #represent that will represent every item in the array.

class Ingredient < OpenStruct
  include Kashmir

  representations do
    rep(:name)
    rep(:quantity)
  end
end

class ClassyRecipe < OpenStruct
  include Kashmir

  representations do
    rep(:title)
    rep(:ingredients)
  end
end
omelette = ClassyRecipe.new(title: 'Omelette Du Fromage')
omelette.ingredients = [
  Ingredient.new(name: 'Egg', quantity: 2),
  Ingredient.new(name: 'Cheese', quantity: 'a lot!')
]

Just describe your Array representations like any regular nested representation.

omelette.represent([:title, { 
    :ingredients => [ :name, :quantity ]
  }
])
=> {
  title: 'Omelette Du Fromage',
  ingredients: [
    { name: 'Egg', quantity: 2 },
    { name: 'Cheese', quantity: 'a lot!' }
  ]
}

Kashmir::Dsl

Passing arrays and hashes around can be very tedious and lead to duplication. Kashmir::Dsl allows you to create your own representers/decorators so you can keep your logic in one place and make way more expressive.

class Recipe < OpenStruct
  include Kashmir

  representations do
    rep(:title)
    rep(:num_steps)
  end
end

class RecipeRepresenter
  include Kashmir::Dsl

  prop :title
  prop :num_steps
end

All you need to do is include Kashmir::Dsl in any ruby class. Every call to prop(field_name) will translate directly into just adding an extra field in the representation array.

In this case, RecipeRepresenter will translate directly to [:title, :num_steps].

brisket = Recipe.new(title: 'BBQ Brisket', num_steps: 2)
brisket.represent(RecipePresenter)

=>  { title: 'BBQ Brisket', num_steps: 2 }

Embedded Representers

It is also possible to define nested representers with embed(:property_name, RepresenterClass).

class RecipeWithChefRepresenter
  include Kashmir::Dsl

  prop :title
  embed :chef, ChefRepresenter
end

class ChefRepresenter
  include Kashmir::Dsl
  
  prop :full_name
end

Kashmir will inline these classes and return a raw Kashmir description.

RecipeWithChefRepresenter.definitions == [ :title, { :chef => [ :full_name ] }]
=> true

Representing the objects will work just as before.

chef = Chef.new(first_name: 'Netto', last_name: 'Farah')
brisket = Recipe.new(title: 'BBQ Brisket', chef: chef)

brisket.represent(RecipeWithChefRepresenter)
 
=> {
  title: 'BBQ Brisket',
  chef: {
    full_name: 'Netto Farah'
  }
}

Inline Representers

You don't necessarily need to define a class for every nested representation.

class RecipeWithInlineChefRepresenter
  include Kashmir::Dsl

  prop :title

  inline :chef do
    prop :full_name
  end
end

Using inline(:property_name, &block) will work the same way as embed. Except that you can now define short representations using ruby blocks. Leading us to our next topic.

Kashmir::InlineDsl

Kashmir::InlineDsl sits right in between raw representations and Representers. It reads much better than arrays of hashes and provides the expressiveness of Kashmir::Dsl without all the ceremony.

It works with every feature from Kashmir::Dsl and allows you to define quick inline descriptions for your Kashmir objects.

class Recipe < OpenStruct
  include Kashmir

  representations do
    rep(:title)
    rep(:num_steps)
  end
end

Just call #represent_with(&block) on any Kashmir object and use the Kashmir::Dsl syntax.

brisket = Recipe.new(title: 'BBQ Brisket', num_steps: 2)

brisket.represent_with do
  prop :title
  prop :num_steps
end

=> { title: 'BBQ Brisket', num_steps: 2 }

Nested Inline Representations

You can nest inline representations using inline(:field, &block) the same way we did with Kashmir::Dsl.

class Ingredient < OpenStruct
  include Kashmir

  representations do
    rep(:name)
    rep(:quantity)
  end
end

class ClassyRecipe < OpenStruct
  include Kashmir

  representations do
    rep(:title)
    rep(:ingredients)
  end
end
omelette = ClassyRecipe.new(title: 'Omelette Du Fromage')
omelette.ingredients = [
  Ingredient.new(name: 'Egg', quantity: 2),
  Ingredient.new(name: 'Cheese', quantity: 'a lot!')
]

Just call #represent_with(&block) and start nesting other inline representations.

omelette.represent_with do
  prop :title
  inline :ingredients do
    prop :name
    prop :quantity
  end
end

=> {
  title: 'Omelette Du Fromage',
  ingredients: [
    { name: 'Egg', quantity: 2 },
    { name: 'Cheese', quantity: 'a lot!' }
  ]
}

Inline representations can become lengthy and confusing over time. If you find yourself nesting more than two levels or including more than 3 or 4 fields per level consider creating Representers with Kashmir::Dsl.

Kashmir::ActiveRecord

Kashmir works just as well with ActiveRecord. ActiveRecord::Relations can be used as Kashmir representations just as any other classes.

Kashmir will attempt to preload every ActiveRecord::Relation defined as representations automatically by using ActiveRecord::Associations::Preloader. This will guarantee that you don't run into N+1 queries while representing collections and dependent objects.

Here's an example of how Kashmir will attempt to optimize database queries:

ActiveRecord::Schema.define do
  create_table :recipes, force: true do |t|
    t.column :title, :string
    t.column :num_steps, :integer
    t.column :chef_id, :integer
  end
  
  create_table :chefs, force: true do |t|
    t.column :name, :string
  end
end
module AR
  class Recipe < ActiveRecord::Base
    include Kashmir

    belongs_to :chef

    representations do
      rep :title
      rep :chef
    end
  end

  class Chef < ActiveRecord::Base
    include Kashmir

    has_many :recipes

    representations do
      rep :name
      rep :recipes
    end
  end
end
AR::Chef.all.each do |chef|
  chef.recipes.to_a
end

will generate

SELECT * FROM chefs
SELECT "recipes".* FROM "recipes" WHERE "recipes"."chef_id" = ?
SELECT "recipes".* FROM "recipes" WHERE "recipes"."chef_id" = ?

With Kashmir:

AR::Chef.all.represent([:recipes])
SELECT "chefs".* FROM "chefs"
SELECT "recipes".* FROM "recipes" WHERE "recipes"."chef_id" IN (1, 2)

For more examples, check out: https://github.com/IFTTT/kashmir/blob/master/test/activerecord_tricks_test.rb

Kashmir::Caching (Experimental)

Caching is the best feature in Kashmir. The Kashmir::Caching module will cache every level of the dependency tree Kashmir generates when representing an object.

Dependency Tree

As you can see in the image above, Kashmir will build a dependency tree of the representation. If you have Caching on, Kashmir will:

  • Build a cache key for each individual object (green)
  • Wrap complex dependencies into their on cache key (blue and pink)
  • Wrap the whole representation into one unique cache key (red)

Each layer gets its own cache keys which can be expired at different times. Kashmir will also be able to fill in blanks in the dependency tree and fetch missing objects individually.

Caching is turned off by default, but you can use one of the two available implementations.

You can also build your own custom caching engine by following the NullCaching protocol available at: https://github.com/IFTTT/kashmir/blob/master/lib/kashmir/plugins/null_caching.rb

Enabling Kashmir::Caching

In Memory

Kashmir.init(
  cache_client: Kashmir::Caching::Memory.new
)

With Memcached

require 'kashmir/plugins/memcached_caching'

client = Dalli::Client.new(url, namespace: 'kashmir', compress: true)
default_ttl = 5.minutes

Kashmir.init(
  cache_client: Kashmir::Caching::Memcached.new(client, default_ttl)
)

For more advanced examples, check out: https://github.com/IFTTT/kashmir/blob/master/test/caching_test.rb

Contributing

  1. Fork it ( https://github.com/[my-github-username]/kashmir/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Author: IFTTT
Source code: https://github.com/IFTTT/kashmir
License: MIT license

#ruby  #ruby-on-rails 

Pass method as parameter using C# | Delegates in C# | C# Bangla Tutorial | Advanced C#

https://youtu.be/GfcTSJf5Rc8

#oop in c# #object oriented programming in c# #object oriented concept in c# #learn oop concept #advance c# #pass method as parameter using c#

Ari  Bogisich

Ari Bogisich

1589816580

Using isdigit() in C/C++

In this article, we’ll take a look at using the isdigit() function in C/C++. This is a very simple way to check if any value is a digit or not. Let’s look at how to use this function, using some simple examples.

#c programming #c++ #c #c#