put a list of one post type in other post type to select from it and display selected item in second post type’s single page

I cannot create a complete solution here, because it’s kinda a ‘work for me for free’ question.

I can (globally) tell you how to accomplish this.

  1. wp-admin –> courses CPT –> add a metabox ‘select teacher(s)’. Collect the teachers with get_posts(). Save the selected teachers as meta, use update_post_meta($course_post_id, 'assigned_teachers', $assigned_teachers) in metabox save function.
  2. In courses single page template, collect the assigned teachers with get_post_meta($course_post_id, 'assigned_teachers', true). If you want to get the link to a teacher post use get_permalink($teacher_post_id).

I hope this is enough to get you started.


UPDATE ( OP added code )

Your first function:

function custom_meta_box_markup($object)
 {
wp_nonce_field(basename(__FILE__), "meta-box-nonce");
?>
 <div>
 <select name="meta-box-dropdown">
 <?php
 $args=array('post_type'=>'mama_ashpaz');
 $q=new WP_Query($args);


  if($q->have_posts()){
  $current=0;
    while($q->have_posts()){
      $q->the_post();?>
 <?php $options[$current]=get_the_title();
   $option[$current]=get_the_id();
   $current++;

   }

   }wp_reset_postdata();
   foreach($options as $key=>$value){
   if($value == get_post_meta($object->ID, "meta-box-dropdown", true))
    {
    ?>
    <option selected><?php echo $value; ?></option>
   <?php
    }
   else
   {
    ?>
  <option><?php echo $value; ?></option>
   <?php
   }

  }
   ?>
  </select>
  </div>
  <?php
 }

Is kinda messy, and you’re not creating the <option> correctly.

Make it like this:

function custom_meta_box_markup($product)

  $options_html="";

  $args = array(
    'posts_per_page' => -1, // get all posts
    'post_type' => 'mama_ashpaz',
  );
  $teacher_posts = get_posts($args);

  $selected_teacher = get_post_meta($product->ID, "selected_teacher", true); // notice the different naming, this is more clear.

  if($teacher_posts) {
    foreach($teacher_posts as $teacher) {

      $selected = '';
      if($teacher->ID == $selected_teacher) $selected = 'selected="selected"';

      // in your code you are not setting the option value.
      // When you save the form and collect it with save_post action hook. Only the 'option value=""' will be passed to the $_POST.
      $options_html .= '<option value="'.$teacher->ID.'" '.$selected.'>'.$teacher->post_title.'</option>';
    }
  }

  // start the Output
  ?>
  <select name="product_teachers_select">
  <?php echo $options_html; ?>
  </select>
  <?php
}

// If you're keeping the above naming, make sure you update the remaining follow-up functions

Now the teacher id is saved. When you retrieve the teacher you will have his id. With his id you can collect any data you want, example:

$teacher = get_post($teacher_id);
$teacher_description = $teacher->post_content;
$teacher_custom_meta = get_post_meta($teacher->ID, 'the_custom_meta_key', true);

Tip:
when you create your code, try to name your params, meta_keys, functions
etc. in a way that anyone can understand what’s going on.
Even for yourself this is very important (imagine looking at your code 2 years from now).

Regards, Bjorn